Updates for new autoconfig.
This commit is contained in:
parent
5eb99ad76e
commit
592ec61b17
|
@ -5,90 +5,129 @@
|
|||
*
|
||||
* Modified by: Charles Hannum, 3/22/94
|
||||
*
|
||||
* $Id: ast.c,v 1.4 1994/03/23 03:55:24 cgd Exp $
|
||||
* $Id: ast.c,v 1.5 1994/03/29 04:35:37 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include "ast.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/pio.h>
|
||||
|
||||
#ifndef NEWCONFIG
|
||||
#include <i386/isa/isa_device.h>
|
||||
|
||||
int astprobe __P((struct isa_device *));
|
||||
int astattach __P((struct isa_device *));
|
||||
|
||||
struct isa_driver astdriver = {
|
||||
astprobe, astattach, "ast"
|
||||
};
|
||||
#endif
|
||||
#include <i386/isa/isavar.h>
|
||||
|
||||
struct ast_softc {
|
||||
struct device sc_dev;
|
||||
u_short sc_iobase;
|
||||
int sc_alive; /* Mask of slave units attached. */
|
||||
int sc_slaves[8]; /* com device unit numbers. XXX - softc ptrs */
|
||||
} ast_softc[NAST];
|
||||
int sc_alive; /* mask of slave units attached */
|
||||
int sc_slaves[8]; /* com device unit numbers */
|
||||
};
|
||||
|
||||
int astprobe();
|
||||
void astattach();
|
||||
|
||||
struct cfdriver astcd = {
|
||||
NULL, "ast", astprobe, astattach, DV_TTY, sizeof(struct ast_softc)
|
||||
};
|
||||
|
||||
int
|
||||
astprobe(dev)
|
||||
struct isa_device *dev;
|
||||
astprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
/*
|
||||
* Do the normal com probe for the first UART and assume
|
||||
* its presence means there is a multiport board there.
|
||||
* XXX needs more robustness.
|
||||
* XXX Needs more robustness.
|
||||
*/
|
||||
return comprobe1(dev->id_iobase);
|
||||
return comprobe1(ia->ia_iobase);
|
||||
}
|
||||
|
||||
struct ast_attach_args {
|
||||
u_short aa_iobase;
|
||||
int aa_slave;
|
||||
};
|
||||
|
||||
int
|
||||
astattach(dev)
|
||||
struct isa_device *dev;
|
||||
astsubmatch(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ast_softc *sc = &ast_softc[dev->id_unit];
|
||||
u_short iobase = dev->id_iobase;
|
||||
unsigned int x;
|
||||
struct ast_softc *sc = (void *)parent;
|
||||
struct ast_attach_args *aa = aux;
|
||||
struct cfdata *cf = self->dv_cfdata;
|
||||
int found, frobbed = 0;
|
||||
#ifdef NEWCONFIG
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", astdriver.name, dev->id_unit);
|
||||
sc->sc_dev.dv_unit = dev->id_unit;
|
||||
#define cf_slave cf_loc[6]
|
||||
if (cf->cf_slave != -1 && cf->cf_slave != aa->aa_slave)
|
||||
return 0;
|
||||
if (cf->cf_iobase == IOBASEUNK) {
|
||||
frobbed = 1;
|
||||
cf->cf_iobase = aa->aa_iobase;
|
||||
}
|
||||
#undef cf_slave
|
||||
#else
|
||||
struct isa_device *id = (void *)cf->cf_loc;
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
if (id->id_physid != -1 && id->id_physid != aa->aa_slave)
|
||||
return 0;
|
||||
if (id->id_iobase == 0) {
|
||||
frobbed = 1;
|
||||
id->id_iobase = aa->aa_iobase;
|
||||
}
|
||||
#endif
|
||||
found = isasubmatch(parent, self, aux);
|
||||
if (found) {
|
||||
sc->sc_slaves[aa->aa_slave] = cf->cf_unit;
|
||||
sc->sc_alive |= 1 << aa->aa_slave;
|
||||
}
|
||||
/*
|
||||
* If we changed the iobase, we have to set it back now, because it
|
||||
* might be a clone device, and the iobase wouldn't get set properly on
|
||||
* the next iteration.
|
||||
*/
|
||||
#ifdef NEWCONFIG
|
||||
if (frobbed)
|
||||
cf->cf_iobase = IOBASEUNK;
|
||||
#else
|
||||
if (frobbed)
|
||||
id->id_iobase = 0;
|
||||
#endif
|
||||
return found;
|
||||
}
|
||||
|
||||
void
|
||||
astattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ast_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct ast_attach_args aa;
|
||||
|
||||
/*
|
||||
* Enable the master interrupt.
|
||||
*/
|
||||
outb(iobase | 0x1f, 0x80);
|
||||
x = inb(iobase | 0x1f);
|
||||
/*
|
||||
* My guess is this bitmask tells you how many ports are there.
|
||||
* I only have a 4-port board to try (returns 0xf). --roland
|
||||
*
|
||||
* It's also not clear that it would be correct to rely on this, since
|
||||
* there might be an interrupt pending on one of the ports, and thus
|
||||
* its bit wouldn't be set. I think the AST protocol simply does not
|
||||
* support more than 4 ports. - mycroft
|
||||
*/
|
||||
printf("%s: 0x%x\n", sc->sc_dev.dv_xname, x);
|
||||
}
|
||||
sc->sc_iobase = ia->ia_iobase;
|
||||
outb(sc->sc_iobase | 0x1f, 0x80);
|
||||
printf("\n");
|
||||
|
||||
void
|
||||
astslave(dev)
|
||||
struct isa_device *dev;
|
||||
{
|
||||
struct ast_softc *sc = &ast_softc[dev->id_parent->id_unit];
|
||||
|
||||
sc->sc_slaves[dev->id_physid] = dev->id_unit;
|
||||
sc->sc_alive |= 1 << dev->id_physid;
|
||||
for (aa.aa_slave = 0, aa.aa_iobase = sc->sc_iobase;
|
||||
aa.aa_slave < 4;
|
||||
aa.aa_slave++, aa.aa_iobase += 8)
|
||||
config_search(astsubmatch, self, &aa);
|
||||
}
|
||||
|
||||
int
|
||||
astintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct ast_softc *sc = &ast_softc[unit];
|
||||
struct ast_softc *sc = astcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
int alive = sc->sc_alive;
|
||||
int bits;
|
||||
|
@ -100,17 +139,12 @@ astintr(unit)
|
|||
do {
|
||||
#define TRY(n) \
|
||||
if ((bits & (1 << (n))) == 0) \
|
||||
comintr(sc->sc_slaves[n]); /* XXX softc ptr */
|
||||
comintr(sc->sc_slaves[n]);
|
||||
TRY(0);
|
||||
TRY(1);
|
||||
TRY(2);
|
||||
TRY(3);
|
||||
#ifdef notdef
|
||||
TRY(4);
|
||||
TRY(5);
|
||||
TRY(6);
|
||||
TRY(7);
|
||||
#endif
|
||||
#undef TRY
|
||||
bits = inb(iobase | 0x1f) & alive;
|
||||
} while (bits != alive);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.18 1994/03/06 17:18:48 mycroft Exp $
|
||||
* $Id: clock.c,v 1.19 1994/03/29 04:35:41 mycroft Exp $
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
|
@ -93,6 +93,7 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/isa.h>
|
||||
|
@ -103,7 +104,7 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
void spinwait __P((int));
|
||||
|
||||
void
|
||||
startrtclock(void)
|
||||
startrtclock()
|
||||
{
|
||||
int s;
|
||||
|
||||
|
@ -126,27 +127,105 @@ void
|
|||
clockintr(frame)
|
||||
clockframe frame;
|
||||
{
|
||||
|
||||
hardclock(&frame);
|
||||
}
|
||||
|
||||
int
|
||||
gettick()
|
||||
{
|
||||
u_char lo, hi;
|
||||
|
||||
/* Don't want someone screwing with the counter while we're here. */
|
||||
disable_intr();
|
||||
/* Select counter 0 and latch it. */
|
||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
|
||||
lo = inb(TIMER_CNTR0);
|
||||
hi = inb(TIMER_CNTR0);
|
||||
enable_intr();
|
||||
return ((hi << 8) | lo);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait "n" microseconds.
|
||||
* Relies on timer 1 counting down from (TIMER_FREQ / hz) at TIMER_FREQ Hz.
|
||||
* Note: timer had better have been programmed before this is first used!
|
||||
* (Note that we use `rate generator' mode, which counts at 1:1; `square
|
||||
* wave' mode counts at 2:1).
|
||||
*/
|
||||
void
|
||||
delay(n)
|
||||
int n;
|
||||
{
|
||||
int limit, tick, otick;
|
||||
|
||||
/*
|
||||
* Read the counter first, so that the rest of the setup overhead is
|
||||
* counted.
|
||||
*/
|
||||
otick = gettick();
|
||||
|
||||
#ifdef __GNUC__
|
||||
/*
|
||||
* Calculate ((n * TIMER_FREQ) / 1e6) using explicit assembler code so
|
||||
* we can take advantage of the intermediate 64-bit quantity to prevent
|
||||
* loss of significance.
|
||||
*/
|
||||
n -= 5;
|
||||
if (n < 0)
|
||||
return;
|
||||
{register int m;
|
||||
__asm __volatile("mul %3"
|
||||
: "=a" (n), "=d" (m)
|
||||
: "0" (n), "r" (TIMER_FREQ));
|
||||
__asm __volatile("div %3"
|
||||
: "=a" (n)
|
||||
: "0" (n), "d" (m), "r" (1000000)
|
||||
: "%edx");}
|
||||
#else
|
||||
/*
|
||||
* Calculate ((n * TIMER_FREQ) / 1e6) without using floating point and
|
||||
* without any avoidable overflows.
|
||||
*/
|
||||
n -= 20;
|
||||
{
|
||||
int sec = n / 1000000,
|
||||
usec = n % 1000000;
|
||||
n = sec * TIMER_FREQ +
|
||||
usec * (TIMER_FREQ / 1000000) +
|
||||
usec * ((TIMER_FREQ % 1000000) / 1000) / 1000 +
|
||||
usec * (TIMER_FREQ % 1000) / 1000000;
|
||||
}
|
||||
#endif
|
||||
|
||||
limit = TIMER_FREQ / hz;
|
||||
|
||||
while (n > 0) {
|
||||
tick = gettick();
|
||||
if (tick > otick)
|
||||
n -= limit - (tick - otick);
|
||||
else
|
||||
n -= otick - tick;
|
||||
otick = tick;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int delaycount; /* calibrated loop variable (1 millisecond) */
|
||||
|
||||
#define FIRST_GUESS 0x2000
|
||||
findcpuspeed(void)
|
||||
findcpuspeed()
|
||||
{
|
||||
unsigned char low;
|
||||
unsigned int remainder;
|
||||
int i;
|
||||
int remainder;
|
||||
|
||||
/* Put counter in count down mode */
|
||||
outb(IO_TIMER1+3, 0x34);
|
||||
outb(IO_TIMER1, 0xff);
|
||||
outb(IO_TIMER1, 0xff);
|
||||
delaycount = FIRST_GUESS;
|
||||
spinwait(1);
|
||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);
|
||||
outb(TIMER_CNTR0, 0xff);
|
||||
outb(TIMER_CNTR0, 0xff);
|
||||
for (i = FIRST_GUESS; i; i--)
|
||||
;
|
||||
/* Read the value left in the counter */
|
||||
low = inb(IO_TIMER1); /* least siginifcant */
|
||||
remainder = inb(IO_TIMER1); /* most significant */
|
||||
remainder = (remainder<<8) + low ;
|
||||
remainder = gettick();
|
||||
/* Formula for delaycount is :
|
||||
* (loopcount * timer clock speed)/ (counter ticks * 1000)
|
||||
*/
|
||||
|
@ -160,43 +239,36 @@ findcpuspeed(void)
|
|||
extern VEC(clk)();
|
||||
|
||||
void
|
||||
enablertclock(void) {
|
||||
enablertclock()
|
||||
{
|
||||
|
||||
setidt(ICU_OFFSET+0, &VEC(clk), SDT_SYS386IGT, SEL_KPL);
|
||||
INTREN(IRQ0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delay for some number of milliseconds.
|
||||
*/
|
||||
void
|
||||
spinwait(int millisecs)
|
||||
rtcinit()
|
||||
{
|
||||
delay(1000 * millisecs);
|
||||
}
|
||||
static int first_rtcopen_ever = 1;
|
||||
|
||||
static int first_rtcopen_ever = 1;
|
||||
if (!first_rtcopen_ever)
|
||||
return;
|
||||
first_rtcopen_ever = 0;
|
||||
|
||||
void
|
||||
rtcinit(void)
|
||||
{
|
||||
if (first_rtcopen_ever) {
|
||||
outb(IO_RTC, RTC_STATUSA);
|
||||
outb(IO_RTC+1, RTC_DIV2 | RTC_RATE6);
|
||||
outb(IO_RTC, RTC_STATUSB);
|
||||
outb(IO_RTC+1, RTC_HM);
|
||||
first_rtcopen_ever = 0;
|
||||
}
|
||||
outb(IO_RTC, RTC_STATUSA);
|
||||
outb(IO_RTC+1, RTC_DIV2 | RTC_RATE6);
|
||||
outb(IO_RTC, RTC_STATUSB);
|
||||
outb(IO_RTC+1, RTC_HM);
|
||||
}
|
||||
|
||||
int
|
||||
rtcget(struct rtc_st *rtc_regs)
|
||||
rtcget(rtc_regs)
|
||||
struct rtc_st *rtc_regs;
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
u_char *regs = (u_char *)rtc_regs;
|
||||
|
||||
if (first_rtcopen_ever) {
|
||||
rtcinit();
|
||||
}
|
||||
rtcinit();
|
||||
outb(IO_RTC, RTC_D);
|
||||
if (inb(IO_RTC+1) & RTC_VRT == 0) return(-1);
|
||||
outb(IO_RTC, RTC_STATUSA);
|
||||
|
@ -210,15 +282,14 @@ rtcget(struct rtc_st *rtc_regs)
|
|||
}
|
||||
|
||||
void
|
||||
rtcput(struct rtc_st *rtc_regs)
|
||||
rtcput(rtc_regs)
|
||||
struct rtc_st *rtc_regs;
|
||||
{
|
||||
u_char x;
|
||||
int i;
|
||||
u_char x;
|
||||
int i;
|
||||
u_char *regs = (u_char *)rtc_regs;
|
||||
|
||||
if (first_rtcopen_ever) {
|
||||
rtcinit();
|
||||
}
|
||||
rtcinit();
|
||||
outb(IO_RTC, RTC_STATUSB);
|
||||
x = inb(IO_RTC+1);
|
||||
outb(IO_RTC, RTC_STATUSB);
|
||||
|
@ -234,20 +305,26 @@ rtcput(struct rtc_st *rtc_regs)
|
|||
static int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
|
||||
static int
|
||||
yeartoday(int year)
|
||||
yeartoday(year)
|
||||
int year;
|
||||
{
|
||||
|
||||
return((year%4) ? 365 : 366);
|
||||
}
|
||||
|
||||
int
|
||||
hexdectodec(char n)
|
||||
hexdectodec(n)
|
||||
char n;
|
||||
{
|
||||
|
||||
return(((n>>4)&0x0F)*10 + (n&0x0F));
|
||||
}
|
||||
|
||||
char
|
||||
dectohexdec(int n)
|
||||
dectohexdec(n)
|
||||
int n;
|
||||
{
|
||||
|
||||
return((char)(((n/10)<<4)&0xF0) | ((n%10)&0x0F));
|
||||
}
|
||||
|
||||
|
@ -267,14 +344,14 @@ inittodr(base)
|
|||
time_t n;
|
||||
int sec, min, hr, dom, mon, yr;
|
||||
int i, days = 0;
|
||||
int ospl;
|
||||
int s;
|
||||
|
||||
ospl = splclock();
|
||||
s = splclock();
|
||||
if (rtcget(&rtclk)) {
|
||||
splx(ospl);
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
splx (ospl);
|
||||
splx(s);
|
||||
|
||||
sec = hexdectodec(rtclk.rtc_sec);
|
||||
min = hexdectodec(rtclk.rtc_min);
|
||||
|
@ -312,13 +389,12 @@ resettodr()
|
|||
struct rtc_st rtclk;
|
||||
time_t n;
|
||||
int diff, i, j;
|
||||
int ospl;
|
||||
int s;
|
||||
|
||||
ospl = splclock();
|
||||
if (rtcget(&rtclk)) {
|
||||
s = splclock();
|
||||
if (rtcget(&rtclk))
|
||||
bzero(&rtclk, sizeof(rtclk));
|
||||
}
|
||||
splx(ospl);
|
||||
splx(s);
|
||||
|
||||
diff = tz.tz_minuteswest * 60;
|
||||
if (tz.tz_dsttime)
|
||||
|
@ -346,7 +422,7 @@ resettodr()
|
|||
|
||||
rtclk.rtc_dom = dectohexdec(++n);
|
||||
|
||||
ospl = splclock();
|
||||
s = splclock();
|
||||
rtcput(&rtclk);
|
||||
splx(ospl);
|
||||
splx(s);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
|
||||
* $Id: com.c,v 1.28 1994/03/25 04:38:01 mycroft Exp $
|
||||
* $Id: com.c,v 1.29 1994/03/29 04:35:44 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -40,7 +40,6 @@
|
|||
* uses National Semiconductor NS16450/NS16550AF UART
|
||||
*/
|
||||
#include "com.h"
|
||||
#include "ast.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -60,7 +59,7 @@
|
|||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/comreg.h>
|
||||
#include <i386/isa/ic/ns16550.h>
|
||||
|
||||
|
@ -69,7 +68,7 @@ struct com_softc {
|
|||
|
||||
u_short sc_iobase;
|
||||
u_char sc_hwflags;
|
||||
#define COM_HW_MULTI 0x01
|
||||
#define COM_HW_NOIEN 0x01
|
||||
#define COM_HW_FIFO 0x02
|
||||
#define COM_HW_CONSOLE 0x40
|
||||
u_char sc_swflags;
|
||||
|
@ -78,20 +77,20 @@ struct com_softc {
|
|||
#define COM_SW_CRTSCTS 0x04
|
||||
#define COM_SW_MDMBUF 0x08
|
||||
u_char sc_msr, sc_mcr;
|
||||
} com_softc[NCOM];
|
||||
};
|
||||
/* XXXX should be in com_softc, but not ready for that yet */
|
||||
struct tty *com_tty[NCOM];
|
||||
|
||||
int comprobe __P((struct isa_device *));
|
||||
int comattach __P((struct isa_device *));
|
||||
int comprobe();
|
||||
void comattach();
|
||||
int comopen __P((dev_t, int, int, struct proc *));
|
||||
int comclose __P((dev_t, int, int, struct proc *));
|
||||
int comintr __P((int));
|
||||
int comparam __P((struct tty *, struct termios *));
|
||||
void comstart __P((struct tty *));
|
||||
|
||||
struct isa_driver comdriver = {
|
||||
comprobe, comattach, "com"
|
||||
struct cfdriver comcd = {
|
||||
NULL, "com", comprobe, comattach, DV_TTY, sizeof(struct com_softc)
|
||||
};
|
||||
|
||||
int comdefaultrate = TTYDEF_SPEED;
|
||||
|
@ -157,65 +156,39 @@ comprobe1(iobase)
|
|||
}
|
||||
|
||||
int
|
||||
comprobe(dev)
|
||||
struct isa_device *dev;
|
||||
comprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[dev->id_unit];
|
||||
u_short iobase = dev->id_iobase;
|
||||
|
||||
if (dev->id_parent) {
|
||||
if (iobase == 0) {
|
||||
/*
|
||||
* For multiport cards, the iobase may be left
|
||||
* unspecified (zero) for slave ports. In
|
||||
* that case we calculate it from the master
|
||||
* (parent) iobase setting and the slave port
|
||||
* number (physid).
|
||||
*/
|
||||
iobase = dev->id_iobase =
|
||||
dev->id_parent->id_iobase + (8 * dev->id_physid);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", comdriver.name, dev->id_unit);
|
||||
sc->sc_dev.dv_unit = dev->id_unit;
|
||||
struct com_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
|
||||
if (!comprobe1(iobase))
|
||||
return 0;
|
||||
|
||||
return COM_NPORTS;
|
||||
ia->ia_iosize = COM_NPORTS;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
comattach(dev)
|
||||
struct isa_device *dev;
|
||||
void
|
||||
comattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
int unit = dev->id_unit;
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
u_short iobase = dev->id_iobase;
|
||||
struct com_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct cfdata *cf = sc->sc_dev.dv_cfdata;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
struct tty *tp;
|
||||
|
||||
if (unit == comconsole)
|
||||
delay(1000);
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_hwflags = 0;
|
||||
sc->sc_hwflags = cf->cf_flags & COM_HW_NOIEN;
|
||||
sc->sc_swflags = 0;
|
||||
|
||||
printf("%s: ", sc->sc_dev.dv_xname);
|
||||
|
||||
printf("%s", sc->sc_dev.dv_xname);
|
||||
#if NAST > 0
|
||||
if (dev->id_parent) {
|
||||
printf(" at 0x%x %s%d slave %d",
|
||||
dev->id_iobase, dev->id_parent->id_driver->name,
|
||||
dev->id_parent->id_unit, dev->id_physid);
|
||||
astslave(dev);
|
||||
sc->sc_hwflags |= COM_HW_MULTI;
|
||||
}
|
||||
#endif
|
||||
printf(": ");
|
||||
if (sc->sc_dev.dv_unit == comconsole)
|
||||
delay(1000);
|
||||
|
||||
/* look for a NS 16550AF UART with FIFOs */
|
||||
outb(iobase + com_fifo,
|
||||
|
@ -224,11 +197,11 @@ comattach(dev)
|
|||
if ((inb(iobase + com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK)
|
||||
if ((inb(iobase + com_fifo) & FIFO_TRIGGER_14) == FIFO_TRIGGER_14) {
|
||||
sc->sc_hwflags |= COM_HW_FIFO;
|
||||
printf("ns16550a, working fifo\n");
|
||||
printf(": ns16550a, working fifo\n");
|
||||
} else
|
||||
printf("ns82550 or ns16550, broken fifo\n");
|
||||
printf(": ns82550 or ns16550, broken fifo\n");
|
||||
else
|
||||
printf("ns82450 or ns16450, no fifo\n");
|
||||
printf(": ns82450 or ns16450, no fifo\n");
|
||||
outb(iobase + com_fifo, 0);
|
||||
|
||||
/* disable interrupts */
|
||||
|
@ -255,11 +228,11 @@ comattach(dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Need to reset baud rate, etc. of next print so reset comconsinit.
|
||||
* Also make sure console is always "hardwired".
|
||||
*/
|
||||
if (unit == comconsole) {
|
||||
if (sc->sc_dev.dv_unit == comconsole) {
|
||||
/*
|
||||
* Need to reset baud rate, etc. of next print so reset
|
||||
* comconsinit. Also make sure console is always "hardwired".
|
||||
*/
|
||||
comconsinit = 0;
|
||||
sc->sc_hwflags |= COM_HW_CONSOLE;
|
||||
sc->sc_swflags |= COM_SW_SOFTCAR;
|
||||
|
@ -279,10 +252,10 @@ comopen(dev, flag, mode, p)
|
|||
int s;
|
||||
int error = 0;
|
||||
|
||||
if (unit >= NCOM)
|
||||
if (unit >= comcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &com_softc[unit];
|
||||
if (!sc->sc_iobase)
|
||||
sc = comcd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
s = spltty();
|
||||
|
@ -322,7 +295,7 @@ comopen(dev, flag, mode, p)
|
|||
(void) inb(iobase + com_data);
|
||||
/* you turn me on, baby */
|
||||
sc->sc_mcr = MCR_DTR | MCR_RTS;
|
||||
if (!(sc->sc_hwflags & COM_HW_MULTI))
|
||||
if (!(sc->sc_hwflags & COM_HW_NOIEN))
|
||||
sc->sc_mcr |= MCR_IENABLE;
|
||||
outb(iobase + com_mcr, sc->sc_mcr);
|
||||
outb(iobase + com_ier,
|
||||
|
@ -365,7 +338,7 @@ comclose(dev, flag, mode, p)
|
|||
struct proc *p;
|
||||
{
|
||||
int unit = COMUNIT(dev);
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
struct com_softc *sc = comcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct tty *tp = com_tty[unit];
|
||||
|
||||
|
@ -436,7 +409,7 @@ comioctl(dev, cmd, data, flag, p)
|
|||
struct proc *p;
|
||||
{
|
||||
int unit = COMUNIT(dev);
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
struct com_softc *sc = comcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct tty *tp = com_tty[unit];
|
||||
int error;
|
||||
|
@ -540,7 +513,7 @@ comparam(tp, t)
|
|||
struct tty *tp;
|
||||
struct termios *t;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[COMUNIT(tp->t_dev)];
|
||||
struct com_softc *sc = comcd.cd_devs[COMUNIT(tp->t_dev)];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
int ospeed = comspeed(t->c_ospeed);
|
||||
u_char cfcr;
|
||||
|
@ -635,7 +608,7 @@ void
|
|||
comstart(tp)
|
||||
struct tty *tp;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[COMUNIT(tp->t_dev)];
|
||||
struct com_softc *sc = comcd.cd_devs[COMUNIT(tp->t_dev)];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
int s;
|
||||
|
||||
|
@ -749,7 +722,7 @@ int
|
|||
comintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
struct com_softc *sc = comcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct tty *tp;
|
||||
u_char code;
|
||||
|
@ -807,7 +780,6 @@ comintr(unit)
|
|||
comcnprobe(cp)
|
||||
struct consdev *cp;
|
||||
{
|
||||
int unit = CONUNIT;
|
||||
|
||||
if (!comprobe1(CONADDR)) {
|
||||
cp->cn_pri = CN_DEAD;
|
||||
|
@ -819,10 +791,8 @@ comcnprobe(cp)
|
|||
if (cdevsw[commajor].d_open == comopen)
|
||||
break;
|
||||
|
||||
com_softc[unit].sc_iobase = CONADDR;
|
||||
|
||||
/* initialize required fields */
|
||||
cp->cn_dev = makedev(commajor, unit);
|
||||
cp->cn_dev = makedev(commajor, CONUNIT);
|
||||
#ifdef COMCONSOLE
|
||||
cp->cn_pri = CN_REMOTE; /* Force a serial port console */
|
||||
#else
|
||||
|
@ -833,10 +803,9 @@ comcnprobe(cp)
|
|||
comcninit(cp)
|
||||
struct consdev *cp;
|
||||
{
|
||||
int unit = CONUNIT;
|
||||
|
||||
cominit(unit, comdefaultrate);
|
||||
comconsole = unit;
|
||||
cominit(CONUNIT, comdefaultrate);
|
||||
comconsole = CONUNIT;
|
||||
comconsinit = 0;
|
||||
}
|
||||
|
||||
|
@ -844,7 +813,7 @@ cominit(unit, rate)
|
|||
int unit, rate;
|
||||
{
|
||||
int s = splhigh();
|
||||
u_short iobase = com_softc[unit].sc_iobase;
|
||||
u_short iobase = CONADDR;
|
||||
u_char stat;
|
||||
|
||||
outb(iobase + com_cfcr, CFCR_DLAB);
|
||||
|
@ -862,7 +831,7 @@ comcngetc(dev)
|
|||
dev_t dev;
|
||||
{
|
||||
int s = splhigh();
|
||||
u_short iobase = com_softc[COMUNIT(dev)].sc_iobase;
|
||||
u_short iobase = CONADDR;
|
||||
u_char stat, c;
|
||||
|
||||
while (((stat = inb(iobase + com_lsr)) & LSR_RXRDY) == 0)
|
||||
|
@ -881,7 +850,7 @@ comcnputc(dev, c)
|
|||
int c;
|
||||
{
|
||||
int s = splhigh();
|
||||
u_short iobase = com_softc[COMUNIT(dev)].sc_iobase;
|
||||
u_short iobase = CONADDR;
|
||||
u_char stat;
|
||||
register int timo;
|
||||
|
||||
|
|
|
@ -13,10 +13,9 @@
|
|||
* Currently supports the Western Digital/SMC 8003 and 8013 series, the 3Com
|
||||
* 3c503, the NE1000 and NE2000, and a variety of similar clones.
|
||||
*
|
||||
* $Id: if_ed.c,v 1.38 1994/03/08 12:21:19 mycroft Exp $
|
||||
* $Id: if_ed.c,v 1.39 1994/03/29 04:35:47 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include "ed.h"
|
||||
#include "bpfilter.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -55,14 +54,14 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/if_edreg.h>
|
||||
|
||||
/*
|
||||
* ed_softc: per line info and status
|
||||
*/
|
||||
struct ed_softc {
|
||||
struct ed_softc {
|
||||
struct device sc_dev;
|
||||
|
||||
struct arpcom sc_arpcom; /* ethernet common */
|
||||
|
@ -101,10 +100,10 @@ struct ed_softc {
|
|||
u_char rec_page_start; /* first page of RX ring-buffer */
|
||||
u_char rec_page_stop; /* last page of RX ring-buffer */
|
||||
u_char next_packet; /* pointer to next unread RX packet */
|
||||
} ed_softc[NED];
|
||||
};
|
||||
|
||||
int ed_probe __P((struct isa_device *));
|
||||
int ed_attach __P((struct isa_device *));
|
||||
int edprobe();
|
||||
void edattach();
|
||||
int edintr __P((int));
|
||||
int ed_ioctl __P((struct ifnet *, int, caddr_t));
|
||||
int ed_start __P((struct ifnet *));
|
||||
|
@ -131,10 +130,8 @@ struct trailer_header {
|
|||
u_short ether_residual;
|
||||
};
|
||||
|
||||
struct isa_driver eddriver = {
|
||||
ed_probe,
|
||||
ed_attach,
|
||||
"ed"
|
||||
struct cfdriver edcd = {
|
||||
NULL, "ed", edprobe, edattach, DV_IFNET, sizeof(struct ed_softc)
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -171,22 +168,20 @@ static u_short ed_790_intr_mask[] = {
|
|||
* Determine if the device is present.
|
||||
*/
|
||||
int
|
||||
ed_probe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
edprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
|
||||
int nports;
|
||||
struct ed_softc *sc = (void *)self;
|
||||
struct cfdata *cf = sc->sc_dev.dv_cfdata;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", eddriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
if (nports = ed_probe_WD80x3(isa_dev))
|
||||
return nports;
|
||||
if (nports = ed_probe_3Com(isa_dev))
|
||||
return nports;
|
||||
if (nports = ed_probe_Novell(isa_dev))
|
||||
return nports;
|
||||
if (ed_probe_WD80x3(sc, cf, ia))
|
||||
return 1;
|
||||
if (ed_probe_3Com(sc, cf, ia))
|
||||
return 1;
|
||||
if (ed_probe_Novell(sc, cf, ia))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -211,11 +206,11 @@ ed_probe(isa_dev)
|
|||
*
|
||||
* Return 1 if 8390 was found, 0 if not.
|
||||
*/
|
||||
|
||||
int
|
||||
ed_probe_generic8390(sc)
|
||||
struct ed_softc *sc;
|
||||
{
|
||||
|
||||
if ((inb(sc->nic_addr + ED_P0_CR) &
|
||||
(ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
|
||||
(ED_CR_RD2 | ED_CR_STP))
|
||||
|
@ -230,15 +225,16 @@ ed_probe_generic8390(sc)
|
|||
* Probe and vendor-specific initialization routine for SMC/WD80x3 boards.
|
||||
*/
|
||||
int
|
||||
ed_probe_WD80x3(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
ed_probe_WD80x3(sc, cf, ia)
|
||||
struct ed_softc *sc;
|
||||
struct cfdata *cf;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
|
||||
int i;
|
||||
u_int memsize;
|
||||
u_char iptr, isa16bit, sum;
|
||||
|
||||
sc->asic_addr = isa_dev->id_iobase;
|
||||
sc->asic_addr = ia->ia_iobase;
|
||||
sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET;
|
||||
sc->is790 = 0;
|
||||
|
||||
|
@ -375,20 +371,20 @@ ed_probe_WD80x3(isa_dev)
|
|||
#ifdef ED_DEBUG
|
||||
printf("type=%x type_str=%s isa16bit=%d memsize=%d id_msize=%d\n",
|
||||
sc->type, sc->type_str ?: "unknown", isa16bit, memsize,
|
||||
isa_dev->id_msize);
|
||||
ia->ia_msize);
|
||||
for (i = 0; i < 8; i++)
|
||||
printf("%x -> %x\n", i, inb(sc->asic_addr + i));
|
||||
#endif
|
||||
/* Allow the user to override the autoconfiguration. */
|
||||
if (isa_dev->id_msize)
|
||||
memsize = isa_dev->id_msize;
|
||||
if (ia->ia_msize)
|
||||
memsize = ia->ia_msize;
|
||||
/*
|
||||
* (Note that if the user specifies both of the following flags that
|
||||
* '8-bit' mode intentionally has precedence.)
|
||||
*/
|
||||
if (isa_dev->id_flags & ED_FLAGS_FORCE_16BIT_MODE)
|
||||
if (cf->cf_flags & ED_FLAGS_FORCE_16BIT_MODE)
|
||||
isa16bit = 1;
|
||||
if (isa_dev->id_flags & ED_FLAGS_FORCE_8BIT_MODE)
|
||||
if (cf->cf_flags & ED_FLAGS_FORCE_8BIT_MODE)
|
||||
isa16bit = 0;
|
||||
|
||||
/*
|
||||
|
@ -400,43 +396,40 @@ ed_probe_WD80x3(isa_dev)
|
|||
if (sc->is790) {
|
||||
sc->ed_cr_rd2 = 0;
|
||||
/* Assemble together the encoded interrupt number. */
|
||||
outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04)
|
||||
| 0x80);
|
||||
iptr = ((inb(isa_dev->id_iobase + 0x0d) & 0x0c) >> 2) |
|
||||
((inb(isa_dev->id_iobase + 0x0d) & 0x40) >> 4);
|
||||
outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04)
|
||||
& ~0x80);
|
||||
outb(ia->ia_iobase + 0x04, inb(ia->ia_iobase + 0x04) | 0x80);
|
||||
iptr = ((inb(ia->ia_iobase + 0x0d) & 0x0c) >> 2) |
|
||||
((inb(ia->ia_iobase + 0x0d) & 0x40) >> 4);
|
||||
outb(ia->ia_iobase + 0x04, inb(ia->ia_iobase + 0x04) & ~0x80);
|
||||
/*
|
||||
* Translate it using translation table, and check for
|
||||
* correctness.
|
||||
*/
|
||||
if (ed_790_intr_mask[iptr] != isa_dev->id_irq) {
|
||||
if (ed_790_intr_mask[iptr] != ia->ia_irq) {
|
||||
printf("%s: kernel configured irq %d doesn't match board configured irq %d\n",
|
||||
sc->sc_dev.dv_xname, ffs(isa_dev->id_irq) - 1,
|
||||
sc->sc_dev.dv_xname, ffs(ia->ia_irq) - 1,
|
||||
ffs(ed_790_intr_mask[iptr]) - 1);
|
||||
return 0;
|
||||
}
|
||||
/* Enable the interrupt. */
|
||||
outb(isa_dev->id_iobase + 0x06, inb(isa_dev->id_iobase + 0x06)
|
||||
| 0x01);
|
||||
outb(ia->ia_iobase + 0x06, inb(ia->ia_iobase + 0x06) | 0x01);
|
||||
} else if (sc->type & ED_WD_SOFTCONFIG) {
|
||||
/* Assemble together the encoded interrupt number. */
|
||||
iptr = (inb(isa_dev->id_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
|
||||
((inb(isa_dev->id_iobase + ED_WD_IRR) &
|
||||
iptr = (inb(ia->ia_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
|
||||
((inb(ia->ia_iobase + ED_WD_IRR) &
|
||||
(ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5);
|
||||
/*
|
||||
* Translate it using translation table, and check for
|
||||
* correctness.
|
||||
*/
|
||||
if (ed_intr_mask[iptr] != isa_dev->id_irq) {
|
||||
if (ed_intr_mask[iptr] != ia->ia_irq) {
|
||||
printf("%s: kernel configured irq %d doesn't match board configured irq %d\n",
|
||||
sc->sc_dev.dv_xname, ffs(isa_dev->id_irq) - 1,
|
||||
sc->sc_dev.dv_xname, ffs(ia->ia_irq) - 1,
|
||||
ffs(ed_intr_mask[iptr]) - 1);
|
||||
return 0;
|
||||
}
|
||||
/* Enable the interrupt. */
|
||||
outb(isa_dev->id_iobase + ED_WD_IRR,
|
||||
inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
|
||||
outb(ia->ia_iobase + ED_WD_IRR,
|
||||
inb(ia->ia_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
|
||||
}
|
||||
|
||||
sc->isa16bit = isa16bit;
|
||||
|
@ -447,21 +440,22 @@ ed_probe_WD80x3(isa_dev)
|
|||
* mode - without mapping the NIC memory shared. ...Not the prefered
|
||||
* way, but it might be the only way.
|
||||
*/
|
||||
if (isa_dev->id_flags & ED_FLAGS_FORCE_PIO) {
|
||||
if (cf->cf_flags & ED_FLAGS_FORCE_PIO) {
|
||||
sc->mem_shared = 0;
|
||||
isa_dev->id_maddr = 0;
|
||||
} else
|
||||
ia->ia_msize = 0;
|
||||
} else {
|
||||
sc->mem_shared = 1;
|
||||
ia->ia_msize = memsize;
|
||||
}
|
||||
#else
|
||||
sc->mem_shared = 1;
|
||||
ia->ia_msize = memsize;
|
||||
#endif
|
||||
isa_dev->id_msize = memsize;
|
||||
|
||||
sc->mem_start = (caddr_t)isa_dev->id_maddr;
|
||||
sc->mem_start = (caddr_t)ia->ia_maddr;
|
||||
|
||||
/* Allocate one xmit buffer if < 16k, two buffers otherwise. */
|
||||
if ((memsize < 16384) ||
|
||||
(isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING))
|
||||
if ((memsize < 16384) || (cf->cf_flags & ED_FLAGS_NO_MULTI_BUFFERING))
|
||||
sc->txb_cnt = 1;
|
||||
else
|
||||
sc->txb_cnt = 2;
|
||||
|
@ -570,23 +564,25 @@ ed_probe_WD80x3(isa_dev)
|
|||
}
|
||||
}
|
||||
|
||||
return ED_WD_IO_PORTS;
|
||||
ia->ia_iosize = ED_WD_IO_PORTS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe and vendor-specific initialization routine for 3Com 3c503 boards.
|
||||
*/
|
||||
int
|
||||
ed_probe_3Com(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
ed_probe_3Com(sc, cf, ia)
|
||||
struct ed_softc *sc;
|
||||
struct cfdata *cf;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
|
||||
int i;
|
||||
u_int memsize;
|
||||
u_char isa16bit, sum;
|
||||
|
||||
sc->asic_addr = isa_dev->id_iobase + ED_3COM_ASIC_OFFSET;
|
||||
sc->nic_addr = isa_dev->id_iobase + ED_3COM_NIC_OFFSET;
|
||||
sc->asic_addr = ia->ia_iobase + ED_3COM_ASIC_OFFSET;
|
||||
sc->nic_addr = ia->ia_iobase + ED_3COM_NIC_OFFSET;
|
||||
sc->ed_cr_rd2 = ED_CR_RD2;
|
||||
|
||||
/*
|
||||
|
@ -599,35 +595,35 @@ ed_probe_3Com(isa_dev)
|
|||
*/
|
||||
switch (inb(sc->asic_addr + ED_3COM_BCFR)) {
|
||||
case ED_3COM_BCFR_300:
|
||||
if (isa_dev->id_iobase != 0x300)
|
||||
if (ia->ia_iobase != 0x300)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_310:
|
||||
if (isa_dev->id_iobase != 0x310)
|
||||
if (ia->ia_iobase != 0x310)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_330:
|
||||
if (isa_dev->id_iobase != 0x330)
|
||||
if (ia->ia_iobase != 0x330)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_350:
|
||||
if (isa_dev->id_iobase != 0x350)
|
||||
if (ia->ia_iobase != 0x350)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_250:
|
||||
if (isa_dev->id_iobase != 0x250)
|
||||
if (ia->ia_iobase != 0x250)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_280:
|
||||
if (isa_dev->id_iobase != 0x280)
|
||||
if (ia->ia_iobase != 0x280)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_2A0:
|
||||
if (isa_dev->id_iobase != 0x2a0)
|
||||
if (ia->ia_iobase != 0x2a0)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_2E0:
|
||||
if (isa_dev->id_iobase != 0x2e0)
|
||||
if (ia->ia_iobase != 0x2e0)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
|
@ -640,26 +636,25 @@ ed_probe_3Com(isa_dev)
|
|||
*/
|
||||
switch (inb(sc->asic_addr + ED_3COM_PCFR)) {
|
||||
case ED_3COM_PCFR_DC000:
|
||||
if (kvtop(isa_dev->id_maddr) != 0xdc000)
|
||||
if (kvtop(ia->ia_maddr) != 0xdc000)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_PCFR_D8000:
|
||||
if (kvtop(isa_dev->id_maddr) != 0xd8000)
|
||||
if (kvtop(ia->ia_maddr) != 0xd8000)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_PCFR_CC000:
|
||||
if (kvtop(isa_dev->id_maddr) != 0xcc000)
|
||||
if (kvtop(ia->ia_maddr) != 0xcc000)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_PCFR_C8000:
|
||||
if (kvtop(isa_dev->id_maddr) != 0xc8000)
|
||||
if (kvtop(ia->ia_maddr) != 0xc8000)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset NIC and ASIC. Enable on-board transceiver throughout reset
|
||||
* sequence because it'll lock up if the cable isn't connected if we
|
||||
|
@ -731,7 +726,7 @@ ed_probe_3Com(isa_dev)
|
|||
/* Select page 0 registers. */
|
||||
outb(sc->nic_addr + ED_P2_CR, ED_CR_RD2 | ED_CR_STP);
|
||||
|
||||
sc->mem_start = (caddr_t)isa_dev->id_maddr;
|
||||
sc->mem_start = (caddr_t)ia->ia_maddr;
|
||||
sc->mem_size = memsize;
|
||||
sc->mem_end = sc->mem_start + memsize;
|
||||
|
||||
|
@ -745,7 +740,7 @@ ed_probe_3Com(isa_dev)
|
|||
* we optimize for linear transfers of same-size packets.)
|
||||
*/
|
||||
if (isa16bit) {
|
||||
if (isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING)
|
||||
if (cf->cf_flags & ED_FLAGS_NO_MULTI_BUFFERING)
|
||||
sc->txb_cnt = 1;
|
||||
else
|
||||
sc->txb_cnt = 2;
|
||||
|
@ -775,7 +770,7 @@ ed_probe_3Com(isa_dev)
|
|||
outb(sc->asic_addr + ED_3COM_PSPR, sc->rec_page_stop);
|
||||
|
||||
/* Set IRQ. 3c503 only allows a choice of irq 3-5 or 9. */
|
||||
switch (isa_dev->id_irq) {
|
||||
switch (ia->ia_irq) {
|
||||
case IRQ9:
|
||||
outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ2);
|
||||
break;
|
||||
|
@ -790,7 +785,7 @@ ed_probe_3Com(isa_dev)
|
|||
break;
|
||||
default:
|
||||
printf("%s: invalid irq configuration (%d) must be 3-5 or 9 for 3c503\n",
|
||||
sc->sc_dev.dv_xname, ffs(isa_dev->id_irq) - 1);
|
||||
sc->sc_dev.dv_xname, ffs(ia->ia_irq) - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -821,25 +816,27 @@ ed_probe_3Com(isa_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
isa_dev->id_msize = memsize;
|
||||
return ED_3COM_IO_PORTS;
|
||||
ia->ia_msize = memsize;
|
||||
ia->ia_iosize = ED_3COM_IO_PORTS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe and vendor-specific initialization routine for NE1000/2000 boards.
|
||||
*/
|
||||
int
|
||||
ed_probe_Novell(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
ed_probe_Novell(sc, cf, ia)
|
||||
struct ed_softc *sc;
|
||||
struct cfdata *cf;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
|
||||
u_int memsize, n;
|
||||
u_char romdata[16], isa16bit = 0, tmp;
|
||||
static u_char test_pattern[32] = "THIS is A memory TEST pattern";
|
||||
u_char test_buffer[32];
|
||||
|
||||
sc->asic_addr = isa_dev->id_iobase + ED_NOVELL_ASIC_OFFSET;
|
||||
sc->nic_addr = isa_dev->id_iobase + ED_NOVELL_NIC_OFFSET;
|
||||
sc->asic_addr = ia->ia_iobase + ED_NOVELL_ASIC_OFFSET;
|
||||
sc->nic_addr = ia->ia_iobase + ED_NOVELL_NIC_OFFSET;
|
||||
sc->ed_cr_rd2 = ED_CR_RD2;
|
||||
|
||||
/* XXX - do Novell-specific probe here */
|
||||
|
@ -884,7 +881,7 @@ ed_probe_Novell(isa_dev)
|
|||
|
||||
sc->vendor = ED_VENDOR_NOVELL;
|
||||
sc->mem_shared = 0;
|
||||
isa_dev->id_maddr = 0;
|
||||
ia->ia_msize = 0;
|
||||
|
||||
/*
|
||||
* Test the ability to read and write to the NIC memory. This has the
|
||||
|
@ -944,8 +941,8 @@ ed_probe_Novell(isa_dev)
|
|||
|
||||
#if 0 /* probably not useful - NE boards only come two ways */
|
||||
/* Allow kernel config file overrides. */
|
||||
if (isa_dev->id_msize)
|
||||
memsize = isa_dev->id_msize;
|
||||
if (ia->ia_msize)
|
||||
memsize = ia->ia_msize;
|
||||
#endif
|
||||
|
||||
sc->mem_size = memsize;
|
||||
|
@ -960,8 +957,7 @@ ed_probe_Novell(isa_dev)
|
|||
* Use one xmit buffer if < 16k, two buffers otherwise (if not told
|
||||
* otherwise).
|
||||
*/
|
||||
if ((memsize < 16384) ||
|
||||
(isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING))
|
||||
if ((memsize < 16384) || (cf->cf_flags & ED_FLAGS_NO_MULTI_BUFFERING))
|
||||
sc->txb_cnt = 1;
|
||||
else
|
||||
sc->txb_cnt = 2;
|
||||
|
@ -979,17 +975,20 @@ ed_probe_Novell(isa_dev)
|
|||
/* Clear any pending interrupts that might have occurred above. */
|
||||
outb(sc->nic_addr + ED_P0_ISR, 0xff);
|
||||
|
||||
return ED_NOVELL_IO_PORTS;
|
||||
ia->ia_iosize = ED_NOVELL_IO_PORTS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Install interface into kernel networking data structures.
|
||||
*/
|
||||
int
|
||||
ed_attach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
edattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
|
||||
struct ed_softc *sc = (void *)self;
|
||||
struct cfdata *cf = sc->sc_dev.dv_cfdata;
|
||||
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
|
@ -999,7 +998,7 @@ ed_attach(isa_dev)
|
|||
|
||||
/* Initialize ifnet structure. */
|
||||
ifp->if_unit = sc->sc_dev.dv_unit;
|
||||
ifp->if_name = eddriver.name;
|
||||
ifp->if_name = edcd.cd_name;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_output = ether_output;
|
||||
ifp->if_start = ed_start;
|
||||
|
@ -1012,7 +1011,7 @@ ed_attach(isa_dev)
|
|||
* Set default state for LINK0 flag (used to disable the tranceiver
|
||||
* for AUI operation), based on compile-time config option.
|
||||
*/
|
||||
if (isa_dev->id_flags & ED_FLAGS_DISABLE_TRANCEIVER)
|
||||
if (cf->cf_flags & ED_FLAGS_DISABLE_TRANCEIVER)
|
||||
ifp->if_flags |= IFF_LINK0;
|
||||
|
||||
/* Attach the interface. */
|
||||
|
@ -1040,8 +1039,7 @@ ed_attach(isa_dev)
|
|||
}
|
||||
|
||||
/* Print additional info when attached. */
|
||||
printf("%s: address %s, ", sc->sc_dev.dv_xname,
|
||||
ether_sprintf(sc->sc_arpcom.ac_enaddr));
|
||||
printf(": address %s, ", ether_sprintf(sc->sc_arpcom.ac_enaddr));
|
||||
|
||||
if (sc->type_str && (*sc->type_str != '\0'))
|
||||
printf("type %s ", sc->type_str);
|
||||
|
@ -1056,7 +1054,6 @@ ed_attach(isa_dev)
|
|||
#if NBPFILTER > 0
|
||||
bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1102,7 +1099,7 @@ int
|
|||
ed_watchdog(unit)
|
||||
short unit;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[unit];
|
||||
struct ed_softc *sc = edcd.cd_devs[unit];
|
||||
|
||||
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
|
||||
++sc->sc_arpcom.ac_if.if_oerrors;
|
||||
|
@ -1306,7 +1303,7 @@ int
|
|||
ed_start(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[ifp->if_unit];
|
||||
struct ed_softc *sc = edcd.cd_devs[ifp->if_unit];
|
||||
struct mbuf *m0, *m;
|
||||
caddr_t buffer;
|
||||
int len;
|
||||
|
@ -1565,7 +1562,7 @@ int
|
|||
edintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[unit];
|
||||
struct ed_softc *sc = edcd.cd_devs[unit];
|
||||
u_char isr;
|
||||
|
||||
/* Set NIC to page 0 registers. */
|
||||
|
@ -1750,7 +1747,7 @@ ed_ioctl(ifp, command, data)
|
|||
int command;
|
||||
caddr_t data;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[ifp->if_unit];
|
||||
struct ed_softc *sc = edcd.cd_devs[ifp->if_unit];
|
||||
register struct ifaddr *ifa = (struct ifaddr *)data;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
int s, error = 0;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
/*
|
||||
* 3COM Etherlink 3C501 device driver
|
||||
*
|
||||
* $Id: if_el.c,v 1.7 1994/03/08 12:21:21 mycroft Exp $
|
||||
* $Id: if_el.c,v 1.8 1994/03/29 04:35:51 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -18,7 +18,6 @@
|
|||
* - Does not currently support multicasts
|
||||
*/
|
||||
|
||||
#include "el.h"
|
||||
#include "bpfilter.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -55,7 +54,7 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/if_elreg.h>
|
||||
|
||||
|
@ -80,16 +79,14 @@ struct el_softc {
|
|||
u_short sc_iobase; /* base I/O addr */
|
||||
caddr_t sc_bpf; /* BPF magic cookie */
|
||||
char sc_pktbuf[EL_BUFSIZ]; /* frame buffer */
|
||||
} el_softc[NEL];
|
||||
};
|
||||
|
||||
/*
|
||||
* prototypes
|
||||
*/
|
||||
int elintr __P((int));
|
||||
static int el_attach __P((struct isa_device *));
|
||||
static int el_init __P((struct el_softc *));
|
||||
static int el_ioctl __P((struct ifnet *, int, caddr_t));
|
||||
static int el_probe __P((struct isa_device *));
|
||||
static int el_start __P((struct ifnet *));
|
||||
static int el_watchdog __P((int));
|
||||
static void el_reset __P((struct el_softc *));
|
||||
|
@ -99,9 +96,12 @@ static inline void elread __P((struct el_softc *, caddr_t, int));
|
|||
static struct mbuf *elget __P((caddr_t, int, int, struct ifnet *));
|
||||
static inline void el_hardreset __P((struct el_softc *));
|
||||
|
||||
int elprobe();
|
||||
void elattach();
|
||||
|
||||
/* isa_driver structure for autoconf */
|
||||
struct isa_driver eldriver = {
|
||||
el_probe, el_attach, "el"
|
||||
struct cfdriver elcd = {
|
||||
NULL, "el", elprobe, elattach, DV_IFNET, sizeof(struct el_softc)
|
||||
};
|
||||
|
||||
struct trailer_header {
|
||||
|
@ -115,12 +115,14 @@ struct trailer_header {
|
|||
* See if the card is there and at the right place.
|
||||
* (XXX - cgd -- needs help)
|
||||
*/
|
||||
static int
|
||||
el_probe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
int
|
||||
elprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct el_softc *sc = &el_softc[isa_dev->id_unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct el_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_char station_addr[ETHER_ADDR_LEN];
|
||||
int i;
|
||||
|
||||
|
@ -131,10 +133,6 @@ el_probe(isa_dev)
|
|||
/* Grab some info for our structure. */
|
||||
sc->sc_iobase = iobase;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", eldriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
/*
|
||||
* Now attempt to grab the station address from the PROM and see if it
|
||||
* contains the 3com vendor code.
|
||||
|
@ -168,7 +166,10 @@ el_probe(isa_dev)
|
|||
dprintf(("Vendor code ok.\n"));
|
||||
/* Copy the station address into the arpcom structure. */
|
||||
bcopy(station_addr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
|
||||
return 1; /* XXX - cgd? */
|
||||
|
||||
ia->ia_iosize = 4; /* XXX */
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -176,11 +177,12 @@ el_probe(isa_dev)
|
|||
* called, we know that the card exists at the given I/O address. We still
|
||||
* assume that the IRQ given is correct.
|
||||
*/
|
||||
static int
|
||||
el_attach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
elattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct el_softc *sc = &el_softc[isa_dev->id_unit];
|
||||
struct el_softc *sc = (void *)self;
|
||||
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
|
@ -191,8 +193,8 @@ el_attach(isa_dev)
|
|||
el_stop(sc);
|
||||
|
||||
/* Initialize ifnet structure. */
|
||||
ifp->if_unit = isa_dev->id_unit;
|
||||
ifp->if_name = eldriver.name;
|
||||
ifp->if_unit = sc->sc_dev.dv_unit;
|
||||
ifp->if_name = elcd.cd_name;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_output = ether_output;
|
||||
ifp->if_start = el_start;
|
||||
|
@ -235,8 +237,7 @@ el_attach(isa_dev)
|
|||
bpfattach(&sc->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
|
||||
#endif
|
||||
|
||||
dprintf(("el_attach() finished.\n"));
|
||||
return 1;
|
||||
dprintf(("elattach() finished.\n"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -340,7 +341,7 @@ static int
|
|||
el_start(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct el_softc *sc = &el_softc[ifp->if_unit];
|
||||
struct el_softc *sc = elcd.cd_devs[ifp->if_unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct mbuf *m, *m0;
|
||||
int s, i, len, retries, done;
|
||||
|
@ -479,7 +480,7 @@ int
|
|||
elintr(unit)
|
||||
int unit;
|
||||
{
|
||||
register struct el_softc *sc = &el_softc[unit];
|
||||
register struct el_softc *sc = elcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
int stat, rxstat, len, done;
|
||||
|
||||
|
@ -732,7 +733,7 @@ el_ioctl(ifp, command, data)
|
|||
int command;
|
||||
caddr_t data;
|
||||
{
|
||||
struct el_softc *sc = &el_softc[ifp->if_unit];
|
||||
struct el_softc *sc = elcd.cd_devs[ifp->if_unit];
|
||||
register struct ifaddr *ifa = (struct ifaddr *)data;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
int s, error = 0;
|
||||
|
@ -826,7 +827,7 @@ static int
|
|||
el_watchdog(unit)
|
||||
int unit;
|
||||
{
|
||||
struct el_softc *sc = &el_softc[unit];
|
||||
struct el_softc *sc = elcd.cd_devs[unit];
|
||||
|
||||
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
|
||||
sc->sc_arpcom.ac_if.if_oerrors++;
|
||||
|
|
|
@ -21,17 +21,14 @@
|
|||
* (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: if_ep.c,v 1.24 1994/03/14 06:57:25 hpeyerl Exp $
|
||||
* $Id: if_ep.c,v 1.25 1994/03/29 04:35:53 mycroft Exp $
|
||||
*/
|
||||
/*
|
||||
* TODO:
|
||||
* Multi-509 configs.
|
||||
* don't pass unit into epstop.
|
||||
* epintr returns an int for magnum. 0=not for me. 1=for me. -1=whoknows?
|
||||
* deallocate mbufs when ifconfig'd down.
|
||||
*/
|
||||
|
||||
#include "ep.h"
|
||||
#include "bpfilter.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -41,6 +38,7 @@
|
|||
#include <sys/errno.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/netisr.h>
|
||||
|
@ -69,9 +67,7 @@
|
|||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/if_epreg.h>
|
||||
#include <i386/isa/elink.h>
|
||||
|
||||
|
@ -82,8 +78,11 @@
|
|||
* Ethernet software status per interface.
|
||||
*/
|
||||
struct ep_softc {
|
||||
struct device sc_dev;
|
||||
struct intrhand sc_ih;
|
||||
|
||||
struct arpcom ep_ac; /* Ethernet common part */
|
||||
short ep_io_addr; /* i/o bus address */
|
||||
short ep_iobase; /* i/o bus address */
|
||||
char ep_connectors; /* Connectors on this card. */
|
||||
#define MAX_MBS 4 /* # of mbufs we keep around */
|
||||
struct mbuf *mb[MAX_MBS]; /* spare mbuf storage. */
|
||||
|
@ -91,29 +90,27 @@ struct ep_softc {
|
|||
int last_mb; /* Last mbuf. */
|
||||
int tx_start_thresh; /* Current TX_start_thresh. */
|
||||
caddr_t bpf; /* BPF "magic cookie" */
|
||||
} ep_softc[NEP];
|
||||
};
|
||||
|
||||
static int epprobe __P((struct isa_device *));
|
||||
static int epattach __P((struct isa_device *));
|
||||
static int epprobe();
|
||||
static void epattach();
|
||||
|
||||
struct isa_driver epdriver = {
|
||||
epprobe,
|
||||
epattach,
|
||||
"ep"
|
||||
struct cfdriver epcd = {
|
||||
NULL, "ep", epprobe, epattach, DV_IFNET, sizeof(struct ep_softc)
|
||||
};
|
||||
|
||||
int epintr __P((int));
|
||||
static int epinit __P((int));
|
||||
static int epioctl __P((struct ifnet * ifp, int, caddr_t));
|
||||
static void epinit __P((struct ep_softc *));
|
||||
static int epioctl __P((struct ifnet *, int, caddr_t));
|
||||
static int epstart __P((struct ifnet *));
|
||||
static int epwatchdog __P((int));
|
||||
static void epreset __P((int));
|
||||
static void epreset __P((struct ep_softc *));
|
||||
static void epread __P((struct ep_softc *));
|
||||
static void epmbufqueue __P((struct ep_softc *));
|
||||
static void epstop __P((int));
|
||||
static void epstop __P((struct ep_softc *));
|
||||
|
||||
static u_short epreadeeprom __P((int id_port, int offset));
|
||||
static int epbusyeeprom __P((struct isa_device * is));
|
||||
static int epbusyeeprom __P((struct ep_softc *));
|
||||
|
||||
/*
|
||||
* Eisa probe routine. If any part of this probe should fail to
|
||||
|
@ -122,10 +119,12 @@ static int epbusyeeprom __P((struct isa_device * is));
|
|||
* at the moment.
|
||||
*/
|
||||
int
|
||||
epprobe(is)
|
||||
struct isa_device *is;
|
||||
epprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ep_softc *sc = &ep_softc[is->id_unit];
|
||||
struct ep_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
int port;
|
||||
int i;
|
||||
int eisa_slot;
|
||||
|
@ -142,18 +141,20 @@ epprobe(is)
|
|||
}
|
||||
k = inw(port + EP_W0_PRODUCT_ID);
|
||||
if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
|
||||
return(isa_epprobe(is));
|
||||
return isa_epprobe(sc, ia);
|
||||
|
||||
k = inw(port + EP_W0_ADDRESS_CFG);
|
||||
k = (k & 0x1f) * 0x10 + 0x200; /* decode base addr. */
|
||||
|
||||
k = inw(port + EP_W0_RESOURCE_CFG);
|
||||
k >>= 12;
|
||||
if (is->id_irq != (1 << ((k == 2) ? 9 : k)))
|
||||
return (isa_epprobe(is));
|
||||
if (ia->ia_irq != (1 << ((k == 2) ? 9 : k)))
|
||||
return isa_epprobe(sc, ia);
|
||||
|
||||
is->id_iobase = port; /* Set the base addr for later */
|
||||
return(0x10);
|
||||
ia->ia_iobase = port; /* Set the base addr for later */
|
||||
ia->ia_iosize = 0x10;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -164,10 +165,10 @@ epprobe(is)
|
|||
* Magnum config holds promise of a fix but we'll have to wait a bit.
|
||||
*/
|
||||
int
|
||||
isa_epprobe(is)
|
||||
struct isa_device *is;
|
||||
isa_epprobe(sc, ia)
|
||||
struct ep_softc *sc;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
struct ep_softc *sc = &ep_softc[is->id_unit];
|
||||
u_short k;
|
||||
|
||||
outw(BASE + EP_COMMAND, GLOBAL_RESET);
|
||||
|
@ -191,12 +192,12 @@ isa_epprobe(is)
|
|||
|
||||
k = epreadeeprom(ELINK_ID_PORT, EEPROM_ADDR_CFG); /* get addr cfg */
|
||||
k = (k & 0x1f) * 0x10 + 0x200; /* decode base addr. */
|
||||
if (k != is->id_iobase)
|
||||
if (k != ia->ia_iobase)
|
||||
return (0);
|
||||
|
||||
k = epreadeeprom(ELINK_ID_PORT, EEPROM_RESOURCE_CFG);
|
||||
k >>= 12;
|
||||
if (is->id_irq != (1 << ((k == 2) ? 9 : k)))
|
||||
if (ia->ia_irq != (1 << ((k == 2) ? 9 : k)))
|
||||
return (0);
|
||||
|
||||
outb(ELINK_ID_PORT, ACTIVATE_ADAPTER_TO_CONFIG);
|
||||
|
@ -204,22 +205,24 @@ isa_epprobe(is)
|
|||
return (0x10); /* 16 bytes of I/O space used. */
|
||||
}
|
||||
|
||||
static int
|
||||
epattach(is)
|
||||
struct isa_device *is;
|
||||
static void
|
||||
epattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ep_softc *sc = &ep_softc[is->id_unit];
|
||||
struct ep_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct ifnet *ifp = &sc->ep_ac.ac_if;
|
||||
u_short i;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
u_short i;
|
||||
|
||||
sc->ep_io_addr = is->id_iobase;
|
||||
printf(": ");
|
||||
|
||||
printf("ep%d: ", is->id_unit);
|
||||
sc->ep_iobase = ia->ia_iobase;
|
||||
|
||||
sc->ep_connectors = 0;
|
||||
i = inw(is->id_iobase + EP_W0_CONFIG_CTRL);
|
||||
i = inw(ia->ia_iobase + EP_W0_CONFIG_CTRL);
|
||||
if (i & IS_AUI) {
|
||||
printf("aui");
|
||||
sc->ep_connectors |= AUI;
|
||||
|
@ -245,11 +248,11 @@ epattach(is)
|
|||
for (i = 0; i < 3; i++) {
|
||||
u_short *p;
|
||||
GO_WINDOW(0);
|
||||
if (epbusyeeprom(is))
|
||||
return (0);
|
||||
if (epbusyeeprom(sc))
|
||||
return;
|
||||
outw(BASE + EP_W0_EEPROM_COMMAND, READ_EEPROM | i);
|
||||
if (epbusyeeprom(is))
|
||||
return (0);
|
||||
if (epbusyeeprom(sc))
|
||||
return;
|
||||
p = (u_short *) & sc->ep_ac.ac_enaddr[i * 2];
|
||||
*p = htons(inw(BASE + EP_W0_EEPROM_DATA));
|
||||
GO_WINDOW(2);
|
||||
|
@ -257,8 +260,8 @@ epattach(is)
|
|||
}
|
||||
printf(" address %s\n", ether_sprintf(sc->ep_ac.ac_enaddr));
|
||||
|
||||
ifp->if_unit = is->id_unit;
|
||||
ifp->if_name = "ep";
|
||||
ifp->if_unit = sc->sc_dev.dv_unit;
|
||||
ifp->if_name = epcd.cd_name;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
|
||||
ifp->if_output = ether_output;
|
||||
|
@ -269,43 +272,43 @@ epattach(is)
|
|||
if_attach(ifp);
|
||||
|
||||
/*
|
||||
* Fill the hardware address into ifa_addr if we find an
|
||||
* AF_LINK entry. We need to do this so bpf's can get the hardware
|
||||
* addr of this card. netstat likes this too!
|
||||
* Search down the ifa address list looking for the AF_LINK type entry
|
||||
* and initialize it.
|
||||
*/
|
||||
ifa = ifp->if_addrlist;
|
||||
while ((ifa != 0) && (ifa->ifa_addr != 0) &&
|
||||
(ifa->ifa_addr->sa_family != AF_LINK))
|
||||
ifa = ifa->ifa_next;
|
||||
|
||||
if ((ifa != 0) && (ifa->ifa_addr != 0)) {
|
||||
sdl = (struct sockaddr_dl *) ifa->ifa_addr;
|
||||
sdl->sdl_type = IFT_ETHER;
|
||||
sdl->sdl_alen = ETHER_ADDR_LEN;
|
||||
sdl->sdl_slen = 0;
|
||||
bcopy(sc->ep_ac.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN);
|
||||
while (ifa && ifa->ifa_addr) {
|
||||
if (ifa->ifa_addr->sa_family == AF_LINK) {
|
||||
/*
|
||||
* Fill in the link-level address for this interface.
|
||||
*/
|
||||
sdl = (struct sockaddr_dl *) ifa->ifa_addr;
|
||||
sdl->sdl_type = IFT_ETHER;
|
||||
sdl->sdl_alen = ETHER_ADDR_LEN;
|
||||
sdl->sdl_slen = 0;
|
||||
bcopy(sc->ep_ac.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN);
|
||||
break;
|
||||
} else
|
||||
ifa = ifa->ifa_next;
|
||||
}
|
||||
|
||||
#if NBPFILTER > 0
|
||||
bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The order in here seems important. Otherwise we may not receive
|
||||
* interrupts. ?!
|
||||
*/
|
||||
static int
|
||||
epinit(unit)
|
||||
int unit;
|
||||
static void
|
||||
epinit(sc)
|
||||
register struct ep_softc *sc;
|
||||
{
|
||||
register struct ep_softc *sc = &ep_softc[unit];
|
||||
register struct ifnet *ifp = &sc->ep_ac.ac_if;
|
||||
int s, i;
|
||||
|
||||
if (ifp->if_addrlist == (struct ifaddr *) 0)
|
||||
return (0);
|
||||
if (ifp->if_addrlist == 0)
|
||||
return;
|
||||
|
||||
s = splimp();
|
||||
while (inb(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
|
||||
|
@ -379,7 +382,6 @@ epinit(unit)
|
|||
|
||||
epstart(ifp);
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const char padmap[] = {0, 3, 2, 1};
|
||||
|
@ -388,7 +390,7 @@ static int
|
|||
epstart(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
register struct ep_softc *sc = &ep_softc[ifp->if_unit];
|
||||
register struct ep_softc *sc = epcd.cd_devs[ifp->if_unit];
|
||||
struct mbuf *m, *top;
|
||||
int s, len, pad;
|
||||
|
||||
|
@ -540,18 +542,18 @@ epintr(unit)
|
|||
int unit;
|
||||
{
|
||||
int status, i;
|
||||
register struct ep_softc *sc = &ep_softc[unit];
|
||||
register struct ep_softc *sc = epcd.cd_devs[unit];
|
||||
struct ifnet *ifp = &sc->ep_ac.ac_if;
|
||||
|
||||
status = 0;
|
||||
checkintr:
|
||||
status = inw(BASE + EP_STATUS) &
|
||||
(S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE | S_CARD_FAILURE);
|
||||
if (status == 0) {
|
||||
/* No interrupts. */
|
||||
outw(BASE + EP_COMMAND, C_INTR_LATCH);
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
loop:
|
||||
/* important that we do this first. */
|
||||
outw(BASE + EP_COMMAND, ACK_INTR | status);
|
||||
|
||||
|
@ -566,9 +568,9 @@ checkintr:
|
|||
epread(sc);
|
||||
}
|
||||
if (status & S_CARD_FAILURE) {
|
||||
printf("ep%d: reset (status: %x)\n", unit, status);
|
||||
printf("%s: reset (status: %x)\n", sc->sc_dev.dv_xname, status);
|
||||
outw(BASE + EP_COMMAND, C_INTR_LATCH);
|
||||
epinit(unit);
|
||||
epinit(sc);
|
||||
return (1);
|
||||
}
|
||||
if (status & S_TX_COMPLETE) {
|
||||
|
@ -599,7 +601,14 @@ checkintr:
|
|||
}
|
||||
epstart(ifp);
|
||||
}
|
||||
goto checkintr;
|
||||
status = inw(BASE + EP_STATUS) &
|
||||
(S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE | S_CARD_FAILURE);
|
||||
if (status == 0) {
|
||||
/* No interrupts. */
|
||||
outw(BASE + EP_COMMAND, C_INTR_LATCH);
|
||||
return (1);
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -764,7 +773,7 @@ epioctl(ifp, cmd, data)
|
|||
caddr_t data;
|
||||
{
|
||||
register struct ifaddr *ifa = (struct ifaddr *) data;
|
||||
struct ep_softc *sc = &ep_softc[ifp->if_unit];
|
||||
struct ep_softc *sc = epcd.cd_devs[ifp->if_unit];
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0;
|
||||
|
||||
|
@ -774,7 +783,7 @@ epioctl(ifp, cmd, data)
|
|||
switch (ifa->ifa_addr->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
epinit(ifp->if_unit); /* before arpwhohas */
|
||||
epinit(sc); /* before arpwhohas */
|
||||
((struct arpcom *) ifp)->ac_ipaddr = IA_SIN(ifa)->sin_addr;
|
||||
arpwhohas((struct arpcom *) ifp, &IA_SIN(ifa)->sin_addr);
|
||||
break;
|
||||
|
@ -793,23 +802,23 @@ epioctl(ifp, cmd, data)
|
|||
sc->ep_ac.ac_enaddr,
|
||||
sizeof(sc->ep_ac.ac_enaddr));
|
||||
}
|
||||
epinit(ifp->if_unit);
|
||||
epinit(sc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
epinit(ifp->if_unit);
|
||||
epinit(sc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SIOCSIFFLAGS:
|
||||
if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
|
||||
ifp->if_flags &= ~IFF_RUNNING;
|
||||
epstop(ifp->if_unit);
|
||||
epstop(sc);
|
||||
break;
|
||||
}
|
||||
if (ifp->if_flags & IFF_UP && (ifp->if_flags & IFF_RUNNING) == 0)
|
||||
epinit(ifp->if_unit);
|
||||
epinit(sc);
|
||||
break;
|
||||
#ifdef notdef
|
||||
case SIOCGHWADDR:
|
||||
|
@ -824,13 +833,13 @@ epioctl(ifp, cmd, data)
|
|||
}
|
||||
|
||||
static void
|
||||
epreset(unit)
|
||||
int unit;
|
||||
epreset(sc)
|
||||
struct ep_softc *sc;
|
||||
{
|
||||
int s = splimp();
|
||||
|
||||
epstop(unit);
|
||||
epinit(unit);
|
||||
epstop(sc);
|
||||
epinit(sc);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
@ -838,16 +847,17 @@ static int
|
|||
epwatchdog(unit)
|
||||
int unit;
|
||||
{
|
||||
log(LOG_ERR, "ep%d: watchdog\n", unit);
|
||||
epreset(unit);
|
||||
register struct ep_softc *sc = epcd.cd_devs[unit];
|
||||
|
||||
log(LOG_ERR, "%s: watchdog\n", sc->sc_dev.dv_xname);
|
||||
epreset(sc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
epstop(unit)
|
||||
int unit;
|
||||
epstop(sc)
|
||||
register struct ep_softc *sc;
|
||||
{
|
||||
register struct ep_softc *sc = &ep_softc[unit];
|
||||
|
||||
outw(BASE + EP_COMMAND, RX_DISABLE);
|
||||
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
|
||||
|
@ -883,6 +893,7 @@ epreadeeprom(id_port, offset)
|
|||
int offset;
|
||||
{
|
||||
int i, data = 0;
|
||||
|
||||
outb(id_port, 0x80 + offset);
|
||||
delay(1000);
|
||||
for (i = 0; i < 16; i++)
|
||||
|
@ -891,25 +902,26 @@ epreadeeprom(id_port, offset)
|
|||
}
|
||||
|
||||
static int
|
||||
epbusyeeprom(is)
|
||||
struct isa_device *is;
|
||||
epbusyeeprom(sc)
|
||||
struct ep_softc *sc;
|
||||
{
|
||||
int i = 0, j;
|
||||
register struct ep_softc *sc = &ep_softc[is->id_unit];
|
||||
int i = 100, j;
|
||||
|
||||
while (i++ < 100) {
|
||||
while (i--) {
|
||||
j = inw(BASE + EP_W0_EEPROM_COMMAND);
|
||||
if (j & EEPROM_BUSY)
|
||||
delay(100);
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (i >= 100) {
|
||||
printf("\nep%d: eeprom failed to come ready.\n", is->id_unit);
|
||||
if (!i) {
|
||||
printf("\n%s: eeprom failed to come ready.\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
return (1);
|
||||
}
|
||||
if (j & EEPROM_TST_MODE) {
|
||||
printf("\nep%d: 3c509 in test mode. Erase pencil mark!\n", is->id_unit);
|
||||
printf("\n%s: 3c509 in test mode. Erase pencil mark!\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* (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: if_epreg.h,v 1.2 1994/01/28 23:44:41 jtc Exp $
|
||||
* $Id: if_epreg.h,v 1.3 1994/03/29 04:35:56 mycroft Exp $
|
||||
*/
|
||||
/**************************************************************************
|
||||
* *
|
||||
|
@ -277,7 +277,7 @@
|
|||
#define ENABLE_DRQ_IRQ 0x0001
|
||||
#define MFG_ID 0x6d50
|
||||
#define PROD_ID 0x9150
|
||||
#define BASE sc->ep_io_addr
|
||||
#define BASE sc->ep_iobase
|
||||
#define GO_WINDOW(x) outw(BASE+EP_COMMAND, WINDOW_SELECT|x)
|
||||
#define AUI 0x1
|
||||
#define BNC 0x2
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_ie.c,v 1.6 1994/03/06 17:19:04 mycroft Exp $
|
||||
* $Id: if_ie.c,v 1.7 1994/03/29 04:35:58 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -100,7 +100,6 @@ interval [sc_maddr, sc_maddr + sc_msize); to make 24-pointers, we subtract
|
|||
iomem, and to make 16-pointers, we subtract sc_maddr and and with 0xffff.
|
||||
*/
|
||||
|
||||
#include "ie.h"
|
||||
#include "bpfilter.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -143,9 +142,7 @@ iomem, and to make 16-pointers, we subtract sc_maddr and and with 0xffff.
|
|||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/ic/i82586.h>
|
||||
#include <i386/isa/if_ieatt.h>
|
||||
#include <i386/isa/if_ie507.h>
|
||||
|
@ -251,10 +248,8 @@ struct ie_softc {
|
|||
#if NBPFILTER > 0
|
||||
caddr_t sc_bpf;
|
||||
#endif
|
||||
} ie_softc[NIE];
|
||||
};
|
||||
|
||||
int ieprobe __P((struct isa_device *));
|
||||
int ieattach __P((struct isa_device *));
|
||||
int iewatchdog __P((/* short */));
|
||||
int ieintr __P((int));
|
||||
int ieinit __P((struct ie_softc *sc));
|
||||
|
@ -286,10 +281,11 @@ int in_ierint = 0;
|
|||
int in_ietint = 0;
|
||||
#endif
|
||||
|
||||
struct isa_driver iedriver = {
|
||||
ieprobe,
|
||||
ieattach,
|
||||
"ie"
|
||||
int ieprobe();
|
||||
void ieattach();
|
||||
|
||||
struct cfdriver iecd = {
|
||||
NULL, "ie", ieprobe, ieattach, DV_IFNET, sizeof(struct ie_softc)
|
||||
};
|
||||
|
||||
#define MK_24(base, ptr) ((caddr_t)((u_long)ptr - (u_long)base))
|
||||
|
@ -350,32 +346,29 @@ ie_ack(sc, mask)
|
|||
}
|
||||
|
||||
int
|
||||
ieprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
ieprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[isa_dev->id_unit];
|
||||
int nports;
|
||||
struct ie_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", iedriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
if (nports = sl_probe(isa_dev, sc))
|
||||
return nports;
|
||||
if (nports = el_probe(isa_dev, sc))
|
||||
return nports;
|
||||
if (sl_probe(sc, ia))
|
||||
return 1;
|
||||
if (el_probe(sc, ia))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sl_probe(isa_dev, sc)
|
||||
struct isa_device *isa_dev;
|
||||
sl_probe(sc, ia)
|
||||
struct ie_softc *sc;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
u_char c;
|
||||
|
||||
sc->sc_iobase = isa_dev->id_iobase;
|
||||
sc->sc_maddr = isa_dev->id_maddr;
|
||||
sc->sc_iobase = ia->ia_iobase;
|
||||
sc->sc_maddr = ia->ia_maddr;
|
||||
|
||||
c = inb(PORT + IEATT_REVISION);
|
||||
switch(SL_BOARD(c)) {
|
||||
|
@ -408,11 +401,11 @@ sl_probe(isa_dev, sc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!isa_dev->id_msize)
|
||||
isa_dev->id_msize = sc->sc_msize;
|
||||
else if (isa_dev->id_msize != sc->sc_msize) {
|
||||
if (!ia->ia_msize)
|
||||
ia->ia_msize = sc->sc_msize;
|
||||
else if (ia->ia_msize != sc->sc_msize) {
|
||||
printf("%s: kernel configured msize %d doesn't match board configured msize %d\n",
|
||||
sc->sc_dev.dv_xname, isa_dev->id_msize, sc->sc_msize);
|
||||
sc->sc_dev.dv_xname, ia->ia_msize, sc->sc_msize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -420,20 +413,21 @@ sl_probe(isa_dev, sc)
|
|||
sc->chan_attn = sl_chan_attn;
|
||||
slel_get_address(sc);
|
||||
|
||||
return 16;
|
||||
ia->ia_iosize = 16;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
el_probe(isa_dev, sc)
|
||||
struct isa_device *isa_dev;
|
||||
el_probe(sc, ia)
|
||||
struct ie_softc *sc;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
u_char c;
|
||||
int i;
|
||||
u_char signature[] = "*3COM*";
|
||||
|
||||
sc->sc_iobase = isa_dev->id_iobase;
|
||||
sc->sc_maddr = isa_dev->id_maddr;
|
||||
sc->sc_iobase = ia->ia_iobase;
|
||||
sc->sc_maddr = ia->ia_maddr;
|
||||
|
||||
/* Reset and put card in CONFIG state without changing address. */
|
||||
elink_reset();
|
||||
|
@ -462,17 +456,17 @@ el_probe(isa_dev, sc)
|
|||
|
||||
c = inb(PORT + IE507_IRQ) & 0x0f;
|
||||
|
||||
if (isa_dev->id_irq != (1 << c)) {
|
||||
if (ia->ia_irq != (1 << c)) {
|
||||
printf("%s: kernel configured irq %d doesn't match board configured irq %d\n",
|
||||
sc->sc_dev.dv_xname, ffs(isa_dev->id_irq) - 1, c);
|
||||
sc->sc_dev.dv_xname, ffs(ia->ia_irq) - 1, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c = (inb(PORT + IE507_MADDR) & 0x1c) + 0xc0;
|
||||
|
||||
if (kvtop(isa_dev->id_maddr) != ((int)c << 12)) {
|
||||
if (kvtop(ia->ia_maddr) != ((int)c << 12)) {
|
||||
printf("%s: kernel configured maddr %x doesn't match board configured maddr %x\n",
|
||||
sc->sc_dev.dv_xname, kvtop(isa_dev->id_maddr),
|
||||
sc->sc_dev.dv_xname, kvtop(ia->ia_maddr),
|
||||
(int)c << 12);
|
||||
return 0;
|
||||
}
|
||||
|
@ -492,11 +486,11 @@ el_probe(isa_dev, sc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!isa_dev->id_msize)
|
||||
isa_dev->id_msize = sc->sc_msize;
|
||||
else if (isa_dev->id_msize != sc->sc_msize) {
|
||||
if (!ia->ia_msize)
|
||||
ia->ia_msize = sc->sc_msize;
|
||||
else if (ia->ia_msize != sc->sc_msize) {
|
||||
printf("%s: kernel configured msize %d doesn't match board configured msize %d\n",
|
||||
sc->sc_dev.dv_xname, isa_dev->id_msize, sc->sc_msize);
|
||||
sc->sc_dev.dv_xname, ia->ia_msize, sc->sc_msize);
|
||||
outb(PORT + IE507_CTRL, EL_CTRL_NRST);
|
||||
return 0;
|
||||
}
|
||||
|
@ -505,23 +499,25 @@ el_probe(isa_dev, sc)
|
|||
sc->chan_attn = el_chan_attn;
|
||||
slel_get_address(sc);
|
||||
|
||||
return 16;
|
||||
ia->ia_iosize = 16;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
|
||||
*/
|
||||
int
|
||||
ieattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
ieattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[isa_dev->id_unit];
|
||||
struct ie_softc *sc = (void *)self;
|
||||
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
|
||||
ifp->if_unit = sc->sc_dev.dv_unit;
|
||||
ifp->if_name = iedriver.name;
|
||||
ifp->if_name = iecd.cd_name;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_output = ether_output;
|
||||
ifp->if_start = iestart;
|
||||
|
@ -570,7 +566,7 @@ int
|
|||
iewatchdog(unit)
|
||||
short unit;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[unit];
|
||||
struct ie_softc *sc = iecd.cd_devs[unit];
|
||||
|
||||
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
|
||||
++sc->sc_arpcom.ac_if.if_oerrors;
|
||||
|
@ -585,7 +581,7 @@ int
|
|||
ieintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[unit];
|
||||
struct ie_softc *sc = iecd.cd_devs[unit];
|
||||
register u_short status;
|
||||
|
||||
status = sc->scb->ie_status;
|
||||
|
@ -1243,7 +1239,7 @@ int
|
|||
iestart(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[ifp->if_unit];
|
||||
struct ie_softc *sc = iecd.cd_devs[ifp->if_unit];
|
||||
struct mbuf *m0, *m;
|
||||
u_char *buffer;
|
||||
u_short len;
|
||||
|
@ -1847,7 +1843,7 @@ ieioctl(ifp, cmd, data)
|
|||
int cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[ifp->if_unit];
|
||||
struct ie_softc *sc = iecd.cd_devs[ifp->if_unit];
|
||||
struct ifaddr *ifa = (struct ifaddr *)data;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
int s, error = 0;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* of this software, nor does the author assume any responsibility
|
||||
* for damages incurred with its use.
|
||||
*
|
||||
* $Id: if_is.c,v 1.25 1994/03/08 12:21:26 mycroft Exp $
|
||||
* $Id: if_is.c,v 1.26 1994/03/29 04:36:01 mycroft Exp $
|
||||
*/
|
||||
|
||||
/* TODO
|
||||
|
@ -19,7 +19,6 @@
|
|||
* 2) Add more of the timers/counters e.g. arpcom.opackets etc.
|
||||
*/
|
||||
|
||||
#include "is.h"
|
||||
#include "bpfilter.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -59,7 +58,7 @@
|
|||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/if_isreg.h>
|
||||
|
||||
|
@ -95,13 +94,8 @@ struct is_softc {
|
|||
int sc_debug;
|
||||
#endif
|
||||
caddr_t sc_bpf; /* BPF "magic cookie" */
|
||||
} is_softc[NIS];
|
||||
};
|
||||
|
||||
int is_probe __P((struct isa_device *));
|
||||
int ne2100_probe __P((struct isa_device *, struct is_softc *));
|
||||
int bicc_probe __P((struct isa_device *, struct is_softc *));
|
||||
int lance_probe __P((struct is_softc *));
|
||||
int is_attach __P((struct isa_device *));
|
||||
int isintr __P((int)); /* XXX can't be renamed till new interrupt code */
|
||||
int is_ioctl __P((struct ifnet *, int, caddr_t));
|
||||
int is_start __P((struct ifnet *));
|
||||
|
@ -122,10 +116,14 @@ void xmit_print __P((struct is_softc *, int));
|
|||
#endif
|
||||
void is_setladrf __P((struct arpcom *, u_long *));
|
||||
|
||||
struct isa_driver isdriver = {
|
||||
is_probe,
|
||||
is_attach,
|
||||
"is"
|
||||
int isprobe();
|
||||
int ne2100_probe __P((struct is_softc *, struct isa_attach_args *));
|
||||
int bicc_probe __P((struct is_softc *, struct isa_attach_args *));
|
||||
int lance_probe __P((struct is_softc *));
|
||||
void isattach();
|
||||
|
||||
struct cfdriver iscd = {
|
||||
NULL, "is", isprobe, isattach, DV_IFNET, sizeof(struct is_softc)
|
||||
};
|
||||
|
||||
struct trailer_header {
|
||||
|
@ -155,20 +153,16 @@ isrdcsr(sc, port)
|
|||
}
|
||||
|
||||
int
|
||||
is_probe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
isprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
int unit = isa_dev->id_unit;
|
||||
register struct is_softc *sc = &is_softc[unit];
|
||||
int nports;
|
||||
struct is_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", isdriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
if (nports = bicc_probe(isa_dev, sc))
|
||||
if (bicc_probe(sc, ia))
|
||||
goto found;
|
||||
if (nports = ne2100_probe(isa_dev, sc))
|
||||
if (ne2100_probe(sc, ia))
|
||||
goto found;
|
||||
return 0;
|
||||
|
||||
|
@ -194,15 +188,15 @@ found:
|
|||
*/
|
||||
sc->sc_init += 8 - ((u_long)sc->sc_init & 7);
|
||||
|
||||
return nports;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ne2100_probe(isa_dev, sc)
|
||||
struct isa_device *isa_dev;
|
||||
ne2100_probe(sc, ia)
|
||||
struct is_softc *sc;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
int i;
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
|
@ -219,15 +213,16 @@ ne2100_probe(isa_dev, sc)
|
|||
for (i = 0; i < ETHER_ADDR_LEN; i++)
|
||||
sc->sc_arpcom.ac_enaddr[i] = inb(iobase + i);
|
||||
|
||||
return 24;
|
||||
ia->ia_iosize = 24;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
bicc_probe(isa_dev, sc)
|
||||
struct isa_device *isa_dev;
|
||||
bicc_probe(sc, ia)
|
||||
struct is_softc *sc;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
int i;
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
|
@ -244,7 +239,8 @@ bicc_probe(isa_dev, sc)
|
|||
for (i = 0; i < ETHER_ADDR_LEN; i++)
|
||||
sc->sc_arpcom.ac_enaddr[i] = inb(iobase + (i * 2));
|
||||
|
||||
return 16;
|
||||
ia->ia_iosize = 16;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -289,17 +285,19 @@ lance_probe(sc)
|
|||
* record. System will initialize the interface when it is ready
|
||||
* to accept packets. We get the ethernet address here.
|
||||
*/
|
||||
int
|
||||
is_attach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
isattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct is_softc *sc = &is_softc[isa_dev->id_unit];
|
||||
struct is_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
|
||||
ifp->if_unit = sc->sc_dev.dv_unit;
|
||||
ifp->if_name = isdriver.name;
|
||||
ifp->if_name = iscd.cd_name;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_output = ether_output;
|
||||
ifp->if_start = is_start;
|
||||
|
@ -308,7 +306,7 @@ is_attach(isa_dev)
|
|||
ifp->if_flags =
|
||||
IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
|
||||
|
||||
isa_dmacascade(isa_dev->id_drq);
|
||||
isa_dmacascade(ia->ia_drq);
|
||||
|
||||
/* Attach the interface. */
|
||||
if_attach(ifp);
|
||||
|
@ -355,7 +353,7 @@ int
|
|||
is_watchdog(unit)
|
||||
short unit;
|
||||
{
|
||||
struct is_softc *sc = &is_softc[unit];
|
||||
struct is_softc *sc = iscd.cd_devs[unit];
|
||||
|
||||
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
|
||||
++sc->sc_arpcom.ac_if.if_oerrors;
|
||||
|
@ -500,7 +498,7 @@ int
|
|||
is_start(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
register struct is_softc *sc = &is_softc[ifp->if_unit];
|
||||
register struct is_softc *sc = iscd.cd_devs[ifp->if_unit];
|
||||
struct mbuf *m0, *m;
|
||||
u_char *buffer;
|
||||
int len;
|
||||
|
@ -632,7 +630,7 @@ outloop:
|
|||
int
|
||||
isintr(unit)
|
||||
{
|
||||
register struct is_softc *sc = &is_softc[unit];
|
||||
register struct is_softc *sc = iscd.cd_devs[unit];
|
||||
u_short isr;
|
||||
|
||||
isr = isrdcsr(sc, 0);
|
||||
|
@ -953,7 +951,7 @@ is_ioctl(ifp, cmd, data)
|
|||
int cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
struct is_softc *sc = &is_softc[ifp->if_unit];
|
||||
struct is_softc *sc = iscd.cd_devs[ifp->if_unit];
|
||||
struct ifaddr *ifa = (struct ifaddr *)data;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
int s, error = 0;
|
||||
|
|
|
@ -20,11 +20,9 @@
|
|||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: lms.c,v 1.9 1994/03/06 17:19:10 mycroft Exp $
|
||||
* $Id: lms.c,v 1.10 1994/03/29 04:36:06 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include "lms.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -42,7 +40,7 @@
|
|||
#include <machine/pio.h>
|
||||
#include <machine/mouse.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
|
||||
#define LMS_DATA 0 /* offset for data port, read-only */
|
||||
#define LMS_SIGN 1 /* offset for signature port, read-write */
|
||||
|
@ -65,21 +63,25 @@ struct lms_softc { /* driver status information */
|
|||
#define LMS_ASLP 0x02 /* waiting for mouse data */
|
||||
u_char sc_status; /* mouse button status */
|
||||
int sc_x, sc_y; /* accumulated motion in the X,Y axis */
|
||||
} lms_softc[NLMS];
|
||||
};
|
||||
|
||||
int lmsprobe __P((struct isa_device *));
|
||||
int lmsattach __P((struct isa_device *));
|
||||
int lmsprobe();
|
||||
void lmsattach();
|
||||
int lmsintr __P((int));
|
||||
|
||||
struct isa_driver lmsdriver = { lmsprobe, lmsattach, "lms" };
|
||||
struct cfdriver lmscd = {
|
||||
NULL, "lms", lmsprobe, lmsattach, DV_TTY, sizeof(struct lms_softc)
|
||||
};
|
||||
|
||||
#define LMSUNIT(dev) (minor(dev))
|
||||
|
||||
int
|
||||
lmsprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
lmsprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
|
||||
/* Configure and check for port present. */
|
||||
outb(iobase + LMS_CONFIG, 0x91);
|
||||
|
@ -96,23 +98,23 @@ lmsprobe(isa_dev)
|
|||
/* Disable interrupts. */
|
||||
outb(iobase + LMS_CNTRL, 0x10);
|
||||
|
||||
return LMS_NPORTS;
|
||||
ia->ia_iosize = LMS_NPORTS;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
lmsattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
lmsattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct lms_softc *sc = &lms_softc[isa_dev->id_unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct lms_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
|
||||
/* Other initialization was done by lmsprobe. */
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_state = 0;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", lmsdriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -123,10 +125,10 @@ lmsopen(dev, flag)
|
|||
int unit = LMSUNIT(dev);
|
||||
struct lms_softc *sc;
|
||||
|
||||
if (unit >= NLMS)
|
||||
if (unit >= lmscd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &lms_softc[unit];
|
||||
if (!sc->sc_iobase)
|
||||
sc = lmscd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
if (sc->sc_state & LMS_OPEN)
|
||||
|
@ -150,7 +152,7 @@ lmsclose(dev, flag)
|
|||
dev_t dev;
|
||||
int flag;
|
||||
{
|
||||
struct lms_softc *sc = &lms_softc[LMSUNIT(dev)];
|
||||
struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
|
||||
|
||||
/* Disable interrupts. */
|
||||
outb(sc->sc_iobase + LMS_CNTRL, 0x10);
|
||||
|
@ -168,7 +170,7 @@ lmsread(dev, uio, flag)
|
|||
struct uio *uio;
|
||||
int flag;
|
||||
{
|
||||
struct lms_softc *sc = &lms_softc[LMSUNIT(dev)];
|
||||
struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
|
||||
int s;
|
||||
int error;
|
||||
size_t length;
|
||||
|
@ -216,7 +218,7 @@ lmsioctl(dev, cmd, addr, flag)
|
|||
caddr_t addr;
|
||||
int flag;
|
||||
{
|
||||
struct lms_softc *sc = &lms_softc[LMSUNIT(dev)];
|
||||
struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
|
||||
struct mouseinfo info;
|
||||
int s;
|
||||
int error;
|
||||
|
@ -265,7 +267,7 @@ int
|
|||
lmsintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct lms_softc *sc = &lms_softc[unit];
|
||||
struct lms_softc *sc = lmscd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
u_char hi, lo, buttons, changed;
|
||||
char dx, dy;
|
||||
|
@ -324,7 +326,7 @@ lmsselect(dev, rw, p)
|
|||
int rw;
|
||||
struct proc *p;
|
||||
{
|
||||
struct lms_softc *sc = &lms_softc[LMSUNIT(dev)];
|
||||
struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
|
||||
int s;
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -46,15 +46,13 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: lpt.c,v 1.14 1994/03/06 17:19:11 mycroft Exp $
|
||||
* $Id: lpt.c,v 1.15 1994/03/29 04:36:08 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Device Driver for AT parallel printer port
|
||||
*/
|
||||
|
||||
#include "lpt.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -70,7 +68,7 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/lptreg.h>
|
||||
|
||||
#define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */
|
||||
|
@ -104,14 +102,14 @@ struct lpt_softc {
|
|||
#define LPT_NOPRIME 0x40 /* don't prime on open */
|
||||
#define LPT_NOINTR 0x80 /* do not use interrupt */
|
||||
u_char sc_control;
|
||||
} lpt_softc[NLPT];
|
||||
};
|
||||
|
||||
int lptprobe __P((struct isa_device *));
|
||||
int lptattach __P((struct isa_device *));
|
||||
int lptprobe();
|
||||
void lptattach();
|
||||
int lptintr __P((int));
|
||||
|
||||
struct isa_driver lptdriver = {
|
||||
lptprobe, lptattach, "lpt"
|
||||
struct cfdriver lptcd = {
|
||||
NULL, "lpt", lptprobe, lptattach, DV_TTY, sizeof(struct lpt_softc)
|
||||
};
|
||||
|
||||
#define LPTUNIT(s) (minor(s) & 0x1f)
|
||||
|
@ -174,10 +172,12 @@ lpt_port_test(port, data, mask)
|
|||
* 3) Set the data and control ports to a value of 0
|
||||
*/
|
||||
int
|
||||
lptprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
lptprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_short port;
|
||||
u_char mask, data;
|
||||
int i;
|
||||
|
@ -226,23 +226,25 @@ lptprobe(isa_dev)
|
|||
outb(iobase + lpt_data, 0);
|
||||
outb(iobase + lpt_control, 0);
|
||||
|
||||
return LPT_NPORTS;
|
||||
ia->ia_iosize = LPT_NPORTS;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
lptattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
lptattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[isa_dev->id_unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
u_short irq = isa_dev->id_irq;
|
||||
struct lpt_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_short irq = ia->ia_irq;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", lptdriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
if (!irq)
|
||||
printf("%s: polled\n", sc->sc_dev.dv_xname);
|
||||
if (irq)
|
||||
printf("\n");
|
||||
else
|
||||
printf(": polled\n");
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_irq = irq;
|
||||
|
@ -266,10 +268,10 @@ lptopen(dev, flag)
|
|||
int error;
|
||||
int spin;
|
||||
|
||||
if (unit >= NLPT)
|
||||
if (unit >= lptcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &lpt_softc[unit];
|
||||
if (!sc->sc_iobase)
|
||||
sc = lptcd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
if (sc->sc_irq == 0 && (flags & LPT_NOINTR) == 0)
|
||||
|
@ -372,7 +374,7 @@ lptclose(dev, flag)
|
|||
int flag;
|
||||
{
|
||||
int unit = LPTUNIT(dev);
|
||||
struct lpt_softc *sc = &lpt_softc[unit];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
|
||||
if (sc->sc_count)
|
||||
|
@ -454,7 +456,7 @@ lptwrite(dev, uio)
|
|||
dev_t dev;
|
||||
struct uio *uio;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[LPTUNIT(dev)];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[LPTUNIT(dev)];
|
||||
size_t n;
|
||||
int error = 0;
|
||||
|
||||
|
@ -483,7 +485,7 @@ int
|
|||
lptintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[unit];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -35,13 +35,11 @@
|
|||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mcd.c,v 1.7 1994/03/06 17:19:13 mycroft Exp $
|
||||
* $Id: mcd.c,v 1.8 1994/03/29 04:36:11 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";*/
|
||||
|
||||
#include "mcd.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -63,7 +61,7 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/mcdreg.h>
|
||||
|
||||
#ifndef MCDDEBUG
|
||||
|
@ -80,13 +78,12 @@
|
|||
/* flags */
|
||||
#define MCDOPEN 0x0001 /* device opened */
|
||||
#define MCDVALID 0x0002 /* parameters loaded */
|
||||
#define MCDINIT 0x0004 /* device is init'd */
|
||||
#define MCDWAIT 0x0008 /* waiting for something */
|
||||
#define MCDLABEL 0x0010 /* label is read */
|
||||
#define MCDREADRAW 0x0020 /* read raw mode (2352 bytes) */
|
||||
#define MCDVOLINFO 0x0040 /* already read volinfo */
|
||||
#define MCDTOC 0x0080 /* already read toc */
|
||||
#define MCDMBXBSY 0x0100 /* local mbx is busy */
|
||||
#define MCDWAIT 0x0004 /* waiting for something */
|
||||
#define MCDLABEL 0x0008 /* label is read */
|
||||
#define MCDREADRAW 0x0010 /* read raw mode (2352 bytes) */
|
||||
#define MCDVOLINFO 0x0020 /* already read volinfo */
|
||||
#define MCDTOC 0x0040 /* already read toc */
|
||||
#define MCDMBXBSY 0x0080 /* local mbx is busy */
|
||||
|
||||
/* status */
|
||||
#define MCDAUDIOBSY MCD_ST_AUDIOBSY /* playing audio */
|
||||
|
@ -129,11 +126,9 @@ struct mcd_softc {
|
|||
short debug;
|
||||
struct buf head; /* head of buf queue */
|
||||
struct mcd_mbx mbx;
|
||||
} mcd_softc[NMCD];
|
||||
};
|
||||
|
||||
/* prototypes */
|
||||
int mcdprobe __P((struct isa_device *));
|
||||
int mcdattach __P((struct isa_device *));
|
||||
int mcdopen __P((dev_t));
|
||||
int mcdclose __P((dev_t));
|
||||
int mcd_start __P((struct mcd_softc *));
|
||||
|
@ -166,8 +161,11 @@ int mcd_play __P((struct mcd_softc *, struct mcd_read2 *));
|
|||
int mcd_pause __P((struct mcd_softc *));
|
||||
int mcd_resume __P((struct mcd_softc *));
|
||||
|
||||
struct isa_driver mcddriver = {
|
||||
mcdprobe, mcdattach, "mcd"
|
||||
int mcdprobe();
|
||||
void mcdattach();
|
||||
|
||||
struct cfdriver mcdcd = {
|
||||
NULL, "mcd", mcdprobe, mcdattach, DV_DISK, sizeof(struct mcd_softc)
|
||||
};
|
||||
|
||||
#define mcd_put(port,byte) outb(port,byte)
|
||||
|
@ -194,18 +192,20 @@ struct isa_driver mcddriver = {
|
|||
#define MCD_S_WAITMODE 3
|
||||
#define MCD_S_WAITREAD 4
|
||||
|
||||
int
|
||||
mcdattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
mcdattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct mcd_softc *sc = &mcd_softc[isa_dev->id_unit];
|
||||
struct mcd_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
#ifdef notyet
|
||||
/* Wire controller for interrupts and DMA. */
|
||||
mcd_configure(cd);
|
||||
mcd_configure(sc);
|
||||
#endif
|
||||
|
||||
sc->flags = MCDINIT;
|
||||
sc->flags = 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -216,10 +216,10 @@ mcdopen(dev)
|
|||
struct mcd_softc *sc;
|
||||
|
||||
unit = MCDUNIT(dev);
|
||||
if (unit >= NMCD)
|
||||
if (unit >= mcdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &mcd_softc[unit];
|
||||
if (!sc->iobase || !(sc->flags & MCDINIT))
|
||||
sc = mcdcd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
part = MCDPART(dev);
|
||||
|
@ -265,7 +265,7 @@ mcdclose(dev)
|
|||
|
||||
unit = MCDUNIT(dev);
|
||||
part = MCDPART(dev);
|
||||
sc = &mcd_softc[unit];
|
||||
sc = mcdcd.cd_devs[unit];
|
||||
|
||||
/* Get status. */
|
||||
mcd_getstat(sc, 1);
|
||||
|
@ -282,7 +282,7 @@ void
|
|||
mcdstrategy(bp)
|
||||
struct buf *bp;
|
||||
{
|
||||
struct mcd_softc *sc = &mcd_softc[MCDUNIT(bp->b_dev)];
|
||||
struct mcd_softc *sc = mcdcd.cd_devs[MCDUNIT(bp->b_dev)];
|
||||
struct buf *qp;
|
||||
int s;
|
||||
|
||||
|
@ -393,7 +393,7 @@ mcdioctl(dev, cmd, addr, flags, p)
|
|||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
struct mcd_softc *sc = &mcd_softc[MCDUNIT(dev)];
|
||||
struct mcd_softc *sc = mcdcd.cd_devs[MCDUNIT(dev)];
|
||||
|
||||
if (!(sc->flags & MCDVALID))
|
||||
return EIO;
|
||||
|
@ -494,7 +494,7 @@ mcdsize(dev)
|
|||
dev_t dev;
|
||||
{
|
||||
int size;
|
||||
struct mcd_softc *sc = &mcd_softc[MCDUNIT(dev)];
|
||||
struct mcd_softc *sc = mcdcd.cd_devs[MCDUNIT(dev)];
|
||||
|
||||
if (mcd_volinfo(sc) >= 0) {
|
||||
sc->blksize = MCDBLK;
|
||||
|
@ -529,22 +529,19 @@ mcd_configure(sc)
|
|||
}
|
||||
|
||||
int
|
||||
mcdprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
mcdprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
int unit = isa_dev->id_unit;
|
||||
struct mcd_softc *sc = &mcd_softc[unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct mcd_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
int i;
|
||||
int st, check;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", mcddriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
#ifdef notyet
|
||||
/* Get irq/drq configuration word. */
|
||||
sc->config = irqs[isa_dev->id_irq];
|
||||
sc->config = irqs[ia->ia_irq];
|
||||
#endif
|
||||
sc->iobase = iobase;
|
||||
|
||||
|
@ -576,7 +573,7 @@ mcdprobe(isa_dev)
|
|||
* driven routines mcd_getreply etc. rather than arbitrary delays.
|
||||
*/
|
||||
|
||||
delay (2000);
|
||||
delay(2000);
|
||||
outb(iobase + mcd_command, MCD_CMDCONTINFO);
|
||||
i = mcd_getreply(sc, DELAY_GETREPLY);
|
||||
|
||||
|
@ -614,7 +611,9 @@ mcdprobe(isa_dev)
|
|||
#ifdef DEBUG
|
||||
printf("Mitsumi drive detected\n");
|
||||
#endif
|
||||
return 4;
|
||||
ia->ia_iosize = 4;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -812,7 +811,7 @@ int
|
|||
mcdintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct mcd_softc *sc = &mcd_softc[unit];
|
||||
struct mcd_softc *sc = mcdcd.cd_devs[unit];
|
||||
u_short iobase = sc->iobase;
|
||||
|
||||
MCD_TRACE("stray interrupt xfer=0x%x\n", inb(iobase + mcd_xfer),
|
||||
|
@ -838,7 +837,7 @@ mcd_doread(state, mbxin)
|
|||
struct mcd_mbx *mbxin;
|
||||
{
|
||||
struct mcd_mbx *mbx = (state != MCD_S_BEGIN) ? mbxsave : mbxin;
|
||||
struct mcd_softc *sc = &mcd_softc[mbx->unit];
|
||||
struct mcd_softc *sc = mcdcd.cd_devs[mbx->unit];
|
||||
u_short iobase = mbx->iobase;
|
||||
struct buf *bp = mbx->bp;
|
||||
|
||||
|
|
|
@ -20,11 +20,9 @@
|
|||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mms.c,v 1.8 1994/02/17 03:39:55 mycroft Exp $
|
||||
* $Id: mms.c,v 1.9 1994/03/29 04:36:16 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include "mms.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -42,7 +40,7 @@
|
|||
#include <machine/pio.h>
|
||||
#include <machine/mouse.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
|
||||
#define MMS_ADDR 0 /* offset for register select */
|
||||
#define MMS_DATA 1 /* offset for InPort data */
|
||||
|
@ -63,21 +61,25 @@ struct mms_softc { /* driver status information */
|
|||
#define MMS_ASLP 0x02 /* waiting for mouse data */
|
||||
u_char sc_status; /* mouse button status */
|
||||
int sc_x, sc_y; /* accumulated motion in the X,Y axis */
|
||||
} mms_softc[NMMS];
|
||||
};
|
||||
|
||||
int mmsprobe __P((struct isa_device *));
|
||||
int mmsattach __P((struct isa_device *));
|
||||
int mmsprobe();
|
||||
void mmsattach();
|
||||
int mmsintr __P((int));
|
||||
|
||||
struct isa_driver mmsdriver = { mmsprobe, mmsattach, "mms" };
|
||||
struct cfdriver mmscd = {
|
||||
NULL, "mms", mmsprobe, mmsattach, DV_TTY, sizeof(struct mms_softc)
|
||||
};
|
||||
|
||||
#define MMSUNIT(dev) (minor(dev))
|
||||
|
||||
int
|
||||
mmsprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
mmsprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
|
||||
/* Read identification register to see if present */
|
||||
if (inb(iobase + MMS_IDENT) != 0xde)
|
||||
|
@ -86,23 +88,23 @@ mmsprobe(isa_dev)
|
|||
/* Seems it was there; reset. */
|
||||
outb(iobase + MMS_ADDR, 0x87);
|
||||
|
||||
return MMS_NPORTS;
|
||||
ia->ia_iosize = MMS_NPORTS;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
mmsattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
mmsattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct mms_softc *sc = &mms_softc[isa_dev->id_unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct mms_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
|
||||
/* Other initialization was done by mmsprobe. */
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_state = 0;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", mmsdriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -113,10 +115,10 @@ mmsopen(dev, flag)
|
|||
int unit = MMSUNIT(dev);
|
||||
struct mms_softc *sc;
|
||||
|
||||
if (unit >= NMMS)
|
||||
if (unit >= mmscd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &mms_softc[unit];
|
||||
if (!sc->sc_iobase)
|
||||
sc = mmscd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
if (sc->sc_state & MMS_OPEN)
|
||||
|
@ -141,7 +143,7 @@ mmsclose(dev, flag)
|
|||
dev_t dev;
|
||||
int flag;
|
||||
{
|
||||
struct mms_softc *sc = &mms_softc[MMSUNIT(dev)];
|
||||
struct mms_softc *sc = mmscd.cd_devs[MMSUNIT(dev)];
|
||||
|
||||
/* Disable interrupts. */
|
||||
outb(sc->sc_iobase + MMS_ADDR, 0x87);
|
||||
|
@ -159,7 +161,7 @@ mmsread(dev, uio, flag)
|
|||
struct uio *uio;
|
||||
int flag;
|
||||
{
|
||||
struct mms_softc *sc = &mms_softc[MMSUNIT(dev)];
|
||||
struct mms_softc *sc = mmscd.cd_devs[MMSUNIT(dev)];
|
||||
int s;
|
||||
int error;
|
||||
size_t length;
|
||||
|
@ -207,7 +209,7 @@ mmsioctl(dev, cmd, addr, flag)
|
|||
caddr_t addr;
|
||||
int flag;
|
||||
{
|
||||
struct mms_softc *sc = &mms_softc[MMSUNIT(dev)];
|
||||
struct mms_softc *sc = mmscd.cd_devs[MMSUNIT(dev)];
|
||||
struct mouseinfo info;
|
||||
int s;
|
||||
int error;
|
||||
|
@ -256,7 +258,7 @@ int
|
|||
mmsintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct mms_softc *sc = &mms_softc[unit];
|
||||
struct mms_softc *sc = mmscd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
u_char buttons, changed, status;
|
||||
char dx, dy;
|
||||
|
@ -319,7 +321,7 @@ mmsselect(dev, rw, p)
|
|||
int rw;
|
||||
struct proc *p;
|
||||
{
|
||||
struct mms_softc *sc = &mms_softc[MMSUNIT(dev)];
|
||||
struct mms_softc *sc = mmscd.cd_devs[MMSUNIT(dev)];
|
||||
int s;
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 1994 Charles Hannum.
|
||||
* Copyright (c) 1990 William Jolitz.
|
||||
* Copyright (c) 1991 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
|
@ -32,7 +33,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: npx.c,v 1.14 1994/03/06 17:19:15 mycroft Exp $
|
||||
* $Id: npx.c,v 1.15 1994/03/29 04:36:18 mycroft Exp $
|
||||
*/
|
||||
#include "npx.h"
|
||||
#if NNPX > 0
|
||||
|
@ -44,6 +45,7 @@
|
|||
#include <sys/proc.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
@ -53,7 +55,7 @@
|
|||
#include <machine/specialreg.h>
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/isa.h>
|
||||
|
||||
/*
|
||||
|
@ -108,12 +110,13 @@ void npxexit __P((struct proc *p));
|
|||
void npxinit __P((u_int control));
|
||||
void npxintr __P((struct intrframe frame));
|
||||
void npxsave __P((struct save87 *addr));
|
||||
static int npxattach __P((struct isa_device *dvp));
|
||||
static int npxprobe __P((struct isa_device *dvp));
|
||||
static int npxprobe1 __P((struct isa_device *dvp));
|
||||
int npxprobe1 __P((struct isa_attach_args *));
|
||||
|
||||
struct isa_driver npxdriver = {
|
||||
npxprobe, npxattach, "npx",
|
||||
int npxprobe();
|
||||
void npxattach();
|
||||
|
||||
struct cfdriver npxcd = {
|
||||
NULL, "npx", npxprobe, npxattach, DV_DULL, sizeof(struct device)
|
||||
};
|
||||
|
||||
u_int npx0mask;
|
||||
|
@ -165,10 +168,12 @@ _probetrap:
|
|||
* to tell npxattach() what to do. Modify device struct if npx doesn't
|
||||
* need to use interrupts. Return 1 if device exists.
|
||||
*/
|
||||
static int
|
||||
npxprobe(dvp)
|
||||
struct isa_device *dvp;
|
||||
int
|
||||
npxprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct isa_attach_args *ia = aux;
|
||||
int result;
|
||||
u_long save_eflags;
|
||||
u_char save_icu1_mask;
|
||||
|
@ -182,20 +187,20 @@ npxprobe(dvp)
|
|||
* install suitable handlers and run with interrupts enabled so we
|
||||
* won't need to do so much here.
|
||||
*/
|
||||
npx_intrno = NRSVIDT + ffs(dvp->id_irq) - 1;
|
||||
npx_intrno = NRSVIDT + ffs(ia->ia_irq) - 1;
|
||||
save_eflags = read_eflags();
|
||||
disable_intr();
|
||||
save_icu1_mask = inb(IO_ICU1 + 1);
|
||||
save_icu2_mask = inb(IO_ICU2 + 1);
|
||||
save_idt_npxintr = idt[npx_intrno];
|
||||
save_idt_npxtrap = idt[16];
|
||||
outb(IO_ICU1 + 1, ~(IRQ_SLAVE | dvp->id_irq));
|
||||
outb(IO_ICU2 + 1, ~(dvp->id_irq >> 8));
|
||||
outb(IO_ICU1 + 1, ~(IRQ_SLAVE | ia->ia_irq));
|
||||
outb(IO_ICU2 + 1, ~(ia->ia_irq >> 8));
|
||||
setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL);
|
||||
setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL);
|
||||
npx_idt_probeintr = idt[npx_intrno];
|
||||
enable_intr();
|
||||
result = npxprobe1(dvp);
|
||||
result = npxprobe1(ia);
|
||||
disable_intr();
|
||||
outb(IO_ICU1 + 1, save_icu1_mask);
|
||||
outb(IO_ICU2 + 1, save_icu2_mask);
|
||||
|
@ -205,15 +210,16 @@ npxprobe(dvp)
|
|||
return (result);
|
||||
}
|
||||
|
||||
static int
|
||||
npxprobe1(dvp)
|
||||
struct isa_device *dvp;
|
||||
int
|
||||
npxprobe1(ia)
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
int control;
|
||||
int status;
|
||||
#ifdef lint
|
||||
npxintr();
|
||||
#endif
|
||||
|
||||
ia->ia_iosize = 16;
|
||||
ia->ia_msize = 0;
|
||||
|
||||
/*
|
||||
* Partially reset the coprocessor, if any. Some BIOS's don't reset
|
||||
* it after a warm boot.
|
||||
|
@ -221,6 +227,7 @@ npxprobe1(dvp)
|
|||
outb(0xf1, 0); /* full reset on some systems, NOP on others */
|
||||
delay(1000);
|
||||
outb(0xf0, 0); /* clear BUSY# latch */
|
||||
|
||||
/*
|
||||
* Prepare to trap all ESC (i.e., NPX) instructions and all WAIT
|
||||
* instructions. We must set the CR0_MP bit and use the CR0_TS
|
||||
|
@ -236,10 +243,12 @@ npxprobe1(dvp)
|
|||
* Setting it should fail or do nothing on lesser processors.
|
||||
*/
|
||||
lcr0(rcr0() | CR0_MP | CR0_NE);
|
||||
|
||||
/*
|
||||
* But don't trap while we're probing.
|
||||
*/
|
||||
stop_emulating();
|
||||
|
||||
/*
|
||||
* Finish resetting the coprocessor, if any. If there is an error
|
||||
* pending, then we may get a bogus IRQ13, but probeintr() will handle
|
||||
|
@ -256,6 +265,7 @@ npxprobe1(dvp)
|
|||
printf("fninit caused %u bogus npx trap(s)\n",
|
||||
npx_traps_while_probing);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check for a status of mostly zero.
|
||||
*/
|
||||
|
@ -282,16 +292,16 @@ npxprobe1(dvp)
|
|||
* Good, exception 16 works.
|
||||
*/
|
||||
npx_ex16 = 1;
|
||||
dvp->id_irq = 0; /* zap the interrupt */
|
||||
return 16;
|
||||
ia->ia_irq = 0; /* zap the interrupt */
|
||||
return 1;
|
||||
}
|
||||
if (npx_intrs_while_probing != 0) {
|
||||
/*
|
||||
* Bad, we are stuck with IRQ13.
|
||||
*/
|
||||
npx_irq13 = 1;
|
||||
npx0mask = dvp->id_irq; /* npxattach too late */
|
||||
return 16;
|
||||
npx0mask = ia->ia_irq; /* npxattach too late */
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Worse, even IRQ13 is broken. Use emulator.
|
||||
|
@ -303,34 +313,34 @@ npxprobe1(dvp)
|
|||
* emulator and say that it has been installed. XXX handle devices
|
||||
* that aren't really devices better.
|
||||
*/
|
||||
dvp->id_irq = 0;
|
||||
return 16;
|
||||
ia->ia_irq = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach routine - announce which it is, and wire into system
|
||||
*/
|
||||
int
|
||||
npxattach(dvp)
|
||||
struct isa_device *dvp;
|
||||
void
|
||||
npxattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
|
||||
if (npx_ex16)
|
||||
printf("npx%d: using exception 16\n", dvp->id_unit);
|
||||
printf(": using exception 16\n");
|
||||
else if (npx_irq13)
|
||||
;
|
||||
printf("\n");
|
||||
else {
|
||||
#ifdef MATH_EMULATE
|
||||
if (npx_exists)
|
||||
printf("npx%d: error reporting broken, using emulator\n",
|
||||
dvp->id_unit);
|
||||
printf("error reporting broken; using emulator\n");
|
||||
else
|
||||
printf("npx%d: emulator\n", dvp->id_unit);
|
||||
printf("emulator\n");
|
||||
#else
|
||||
panic("npxattach: no math emulator in kernel!");
|
||||
#endif
|
||||
}
|
||||
npxinit(__INITIAL_NPXCW__);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pccons.c 5.11 (Berkeley) 5/21/91
|
||||
* $Id: pccons.c,v 1.60 1994/03/12 03:45:05 mycroft Exp $
|
||||
* $Id: pccons.c,v 1.61 1994/03/29 04:36:23 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -65,9 +65,9 @@
|
|||
#include <machine/pc/display.h>
|
||||
#include <machine/pccons.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/kbdreg.h>
|
||||
|
||||
#define XFREE86_BUG_COMPAT
|
||||
|
@ -111,10 +111,11 @@ static struct video_state {
|
|||
char so_at; /* standout attributes */
|
||||
} vs;
|
||||
|
||||
int pcprobe(), pcattach();
|
||||
int pcprobe();
|
||||
void pcattach();
|
||||
|
||||
struct isa_driver pcdriver = {
|
||||
pcprobe, pcattach, "pc",
|
||||
struct cfdriver pccd = {
|
||||
NULL, "pc", pcprobe, pcattach, DV_TTY, sizeof(struct device)
|
||||
};
|
||||
|
||||
#define COL 80
|
||||
|
@ -313,9 +314,11 @@ async_update()
|
|||
* these are both bad jokes
|
||||
*/
|
||||
int
|
||||
pcprobe(dev)
|
||||
struct isa_device *dev;
|
||||
pcprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_char c;
|
||||
|
||||
/* Enable interrupts and keyboard, etc. */
|
||||
|
@ -385,21 +388,18 @@ lose:
|
|||
*/
|
||||
#endif
|
||||
|
||||
return 16;
|
||||
ia->ia_iosize = 16;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
pcattach(dev)
|
||||
struct isa_device *dev;
|
||||
void
|
||||
pcattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
|
||||
printf("pc%d: ", dev->id_unit);
|
||||
if (vs.color == 0)
|
||||
printf("mono");
|
||||
else
|
||||
printf("color");
|
||||
printf("\n");
|
||||
|
||||
printf(": %s\n", vs.color ? "color" : "mono");
|
||||
do_async_update(1);
|
||||
}
|
||||
|
||||
|
@ -412,13 +412,13 @@ pcopen(dev, flag, mode, p)
|
|||
int unit = PCUNIT(dev);
|
||||
struct tty *tp;
|
||||
|
||||
if (unit >= NPC)
|
||||
if (unit >= pccd.cd_ndevs)
|
||||
return ENXIO;
|
||||
|
||||
if (!pc_tty[0])
|
||||
tp = pc_tty[0] = ttymalloc();
|
||||
if (!pc_tty[unit])
|
||||
tp = pc_tty[unit] = ttymalloc();
|
||||
else
|
||||
tp = pc_tty[0];
|
||||
tp = pc_tty[unit];
|
||||
|
||||
tp->t_oproc = pcstart;
|
||||
tp->t_param = pcparam;
|
||||
|
@ -446,7 +446,7 @@ pcclose(dev, flag, mode, p)
|
|||
int flag, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct tty *tp = pc_tty[0];
|
||||
register struct tty *tp = pc_tty[PCUNIT(dev)];
|
||||
|
||||
(*linesw[tp->t_line].l_close)(tp, flag);
|
||||
ttyclose(tp);
|
||||
|
|
|
@ -30,23 +30,21 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: sb.c,v 1.5 1994/03/06 17:19:16 mycroft Exp $
|
||||
* $Id: sb.c,v 1.6 1994/03/29 04:36:26 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include "sb.h"
|
||||
#if NSB > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
|
||||
#include "sbreg.h"
|
||||
|
@ -66,15 +64,14 @@
|
|||
* most basic communications with the sb card.
|
||||
*/
|
||||
struct sb_softc {
|
||||
#ifdef NEWCONFIG
|
||||
struct device sc_dev; /* base device */
|
||||
struct isadev sc_id; /* ISA device */
|
||||
struct intrhand sc_ih; /* interrupt vectoring */
|
||||
#endif
|
||||
|
||||
u_short sc_open; /* reference count of open calls */
|
||||
u_short sc_dmachan; /* dma channel */
|
||||
u_long sc_locked; /* true when doing HS DMA */
|
||||
u_long sc_base; /* I/O port base address */
|
||||
u_short sc_locked; /* true when doing HS DMA */
|
||||
u_short sc_iobase; /* I/O port base address */
|
||||
u_short sc_adacmode; /* low/high speed mode indicator */
|
||||
#define SB_ADAC_LS 0
|
||||
#define SB_ADAC_HS 1
|
||||
|
@ -85,21 +82,17 @@ struct sb_softc {
|
|||
void *sc_arg; /* arg for sc_intr() */
|
||||
};
|
||||
|
||||
int sbreset(u_long);
|
||||
int sbreset __P((struct sb_softc *));
|
||||
void sb_spkron __P((struct sb_softc *));
|
||||
void sb_spkroff __P((struct sb_softc *));
|
||||
|
||||
void sb_spkron(struct sb_softc *);
|
||||
void sb_spkroff(struct sb_softc *);
|
||||
static int wdsp(u_short iobase, int v);
|
||||
static int rdsp(u_short iobase);
|
||||
|
||||
static int wdsp(u_long base, int v);
|
||||
static int rdsp(u_long base);
|
||||
|
||||
/* XXX */
|
||||
#define splsb splhigh
|
||||
/* XXX */
|
||||
struct sb_softc *sb_softc;
|
||||
#define splsb splhigh /* XXX */
|
||||
struct sb_softc *sb_softc; /* XXX */
|
||||
|
||||
#ifndef NEWCONFIG
|
||||
struct sb_softc sb_softcs[NSB];
|
||||
#define at_dma(flags, ptr, cc, chan) isa_dmastart(flags, ptr, cc, chan)
|
||||
#endif
|
||||
|
||||
|
@ -109,60 +102,73 @@ struct {
|
|||
int wmidi;
|
||||
} sberr;
|
||||
|
||||
int sbintr __P((int));
|
||||
int sbprobe();
|
||||
void sbattach();
|
||||
#ifdef NEWCONFIG
|
||||
int sbintr(struct sb_softc *);
|
||||
int sbprobe(struct device *, struct cfdata *, void *);
|
||||
void sbattach(struct device *, struct device *, void *);
|
||||
void sbforceintr(void *);
|
||||
#endif
|
||||
|
||||
struct cfdriver sbcd =
|
||||
{ NULL, "sb", sbprobe, sbattach, sizeof(struct sb_softc) };
|
||||
struct cfdriver sbcd = {
|
||||
NULL, "sb", sbprobe, sbattach, DV_DULL, sizeof(struct sb_softc)
|
||||
};
|
||||
|
||||
int
|
||||
sbprobe(struct device *parent, struct cfdata *cf, void *aux)
|
||||
sbprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
register struct isa_attach_args *ia = (struct isa_attach_args *)aux;
|
||||
register int base = ia->ia_iobase;
|
||||
register struct sb_softc *sc = (void *)self;
|
||||
register struct isa_attach_args *ia = aux;
|
||||
register u_short iobase = ia->ia_iobase;
|
||||
|
||||
if (!SB_BASE_VALID(base)) {
|
||||
printf("sb: configured dma chan %d invalid\n", ia->ia_drq);
|
||||
return (0);
|
||||
if (!SB_BASE_VALID(ia->ia_iobase)) {
|
||||
printf("sb: configured iobase %d invalid\n", ia->ia_iobase);
|
||||
return 0;
|
||||
}
|
||||
ia->ia_iosize = SB_NPORT;
|
||||
if (sbreset(base) < 0) {
|
||||
sc->sc_iobase = iobase;
|
||||
if (sbreset(sc) < 0) {
|
||||
printf("sb: couldn't reset card\n");
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Cannot auto-discover DMA channel.
|
||||
*/
|
||||
if (!SB_DRQ_VALID(ia->ia_drq)) {
|
||||
printf("sb: configured dma chan %d invalid\n", ia->ia_drq);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
#ifdef NEWCONFIG
|
||||
/*
|
||||
* If the IRQ wasn't compiled in, auto-detect it.
|
||||
*/
|
||||
if (ia->ia_irq == IRQUNK) {
|
||||
ia->ia_irq = isa_discoverintr(sbforceintr, aux);
|
||||
sbreset(base);
|
||||
sbreset(iobase);
|
||||
if (!SB_IRQ_VALID(ia->ia_irq)) {
|
||||
printf("sb: couldn't auto-detect interrupt");
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
} else if (!SB_IRQ_VALID(ia->ia_irq)) {
|
||||
} else
|
||||
#endif
|
||||
if (!SB_IRQ_VALID(ia->ia_irq)) {
|
||||
int irq = ffs(ia->ia_irq) - 1;
|
||||
printf("sb: configured irq %d invalid\n", irq);
|
||||
return 0;
|
||||
}
|
||||
return (15);
|
||||
ia->ia_iosize = SB_NPORT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef NEWCONFIG
|
||||
void
|
||||
sbforceintr(void *arg)
|
||||
sbforceintr(aux)
|
||||
void *aux;
|
||||
{
|
||||
static char dmabuf;
|
||||
struct isa_attach_args *ia = (struct isa_attach_args *)arg;
|
||||
int base = ia->ia_iobase;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
|
||||
/*
|
||||
* Set up a DMA read of one byte.
|
||||
* XXX Note that at this point we haven't called
|
||||
|
@ -175,11 +181,12 @@ sbforceintr(void *arg)
|
|||
* never need the buffer anyway.)
|
||||
*/
|
||||
at_dma(1, &dmabuf, 1, ia->ia_drq);
|
||||
if (wdsp(base, SB_DSP_RDMA) == 0) {
|
||||
(void)wdsp(base, 0);
|
||||
(void)wdsp(base, 0);
|
||||
if (wdsp(iobase, SB_DSP_RDMA) == 0) {
|
||||
(void)wdsp(iobase, 0);
|
||||
(void)wdsp(iobase, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sbattach(parent, self, aux)
|
||||
|
@ -188,15 +195,17 @@ sbattach(parent, self, aux)
|
|||
{
|
||||
register struct sb_softc *sc = (struct sb_softc *)self;
|
||||
struct isa_attach_args *ia = (struct isa_attach_args *)aux;
|
||||
register int base = ia->ia_iobase;
|
||||
register u_short iobase = ia->ia_iobase;
|
||||
register int vers;
|
||||
|
||||
/* XXX */
|
||||
sb_softc = sc;
|
||||
|
||||
sc->sc_base = base;
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_dmachan = ia->ia_drq;
|
||||
sc->sc_locked = 0;
|
||||
|
||||
#ifdef NEWCONFIG
|
||||
isa_establish(&sc->sc_id, &sc->sc_dev);
|
||||
sc->sc_ih.ih_fun = sbintr;
|
||||
sc->sc_ih.ih_arg = (void *)sc;
|
||||
|
@ -214,101 +223,43 @@ sbattach(parent, self, aux)
|
|||
* is plenty long enough to amortize any fixed time overhead.
|
||||
*/
|
||||
at_setup_dmachan(sc->sc_dmachan, NBPG);
|
||||
|
||||
vers = sbversion(base);
|
||||
printf(" dsp v%d.%d\n", vers >> 8, vers & 0xff);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NEWCONFIG
|
||||
int sbintr(int unit);
|
||||
int sbprobe(struct isa_device *dev);
|
||||
int sbattach(struct isa_device *dev);
|
||||
|
||||
struct isa_driver sbdriver = { sbprobe, sbattach, "sb" };
|
||||
|
||||
int
|
||||
sbprobe(struct isa_device *dev)
|
||||
{
|
||||
register int base = dev->id_iobase;
|
||||
|
||||
if (!SB_BASE_VALID(base)) {
|
||||
printf("sb: configured dma chan %d invalid\n", dev->id_drq);
|
||||
return (0);
|
||||
}
|
||||
if (sbreset(base) < 0) {
|
||||
printf("sb: couldn't reset card\n");
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* Cannot auto-discover DMA channel.
|
||||
*/
|
||||
if (!SB_DRQ_VALID(dev->id_drq)) {
|
||||
printf("sb: configured dma chan %d invalid\n", dev->id_drq);
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* If the IRQ wasn't compiled in, auto-detect it.
|
||||
*/
|
||||
if (dev->id_irq == 0) {
|
||||
printf("sb: no irq configured\n");
|
||||
return (0);
|
||||
} else if (!SB_IRQ_VALID(dev->id_irq)) {
|
||||
int irq = ffs(dev->id_irq) - 1;
|
||||
printf("sb: configured irq %d invalid\n", irq);
|
||||
return (0);
|
||||
}
|
||||
return (15);
|
||||
vers = sbversion(sc);
|
||||
printf(": dsp v%d.%d\n", vers >> 8, vers & 0xff);
|
||||
}
|
||||
|
||||
#define UNIT(x) (minor(x) & 0xf)
|
||||
|
||||
int
|
||||
sbattach(struct isa_device *dev)
|
||||
{
|
||||
int unit = UNIT(dev->id_unit);
|
||||
register struct sb_softc *sc = &sb_softcs[unit];
|
||||
register int base = dev->id_iobase;
|
||||
register int vers;
|
||||
|
||||
/* XXX */
|
||||
sb_softc = sc;
|
||||
|
||||
sc->sc_base = base;
|
||||
sc->sc_dmachan = dev->id_drq;
|
||||
sc->sc_locked = 0;
|
||||
|
||||
vers = sbversion(base);
|
||||
printf("sb%d: dsp v%d.%d\n", unit, vers >> 8, vers & 0xff);
|
||||
}
|
||||
#endif
|
||||
#define SBUNIT(x) (minor(x) & 0xf)
|
||||
|
||||
struct sb_softc *
|
||||
sbopen()
|
||||
{
|
||||
/* XXXX */
|
||||
struct sb_softc *sc = sb_softc;
|
||||
|
||||
if (sc == 0)
|
||||
return 0;
|
||||
|
||||
if (sc->sc_open == 0 && sbreset(sc->sc_base) == 0) {
|
||||
if (sc->sc_open == 0 && sbreset(sc) == 0) {
|
||||
sc->sc_open = 1;
|
||||
sc->sc_mintr = 0;
|
||||
sc->sc_intr = 0;
|
||||
return (sc);
|
||||
return sc;
|
||||
}
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sbclose(struct sb_softc *sc)
|
||||
sbclose(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
|
||||
sc->sc_open = 0;
|
||||
sb_spkroff(sc);
|
||||
sc->sc_intr = 0;
|
||||
sc->sc_mintr = 0;
|
||||
/* XXX this will turn off any dma */
|
||||
sbreset(sc->sc_base);
|
||||
sbreset(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -317,35 +268,35 @@ sbclose(struct sb_softc *sc)
|
|||
* polling loop and wait until it can take the byte.
|
||||
*/
|
||||
static int
|
||||
wdsp(u_long base, int v)
|
||||
wdsp(u_short iobase, int v)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 100; --i >= 0; ) {
|
||||
if ((inb(base + SBP_DSP_WSTAT) & SB_DSP_BUSY) != 0)
|
||||
if ((inb(iobase + SBP_DSP_WSTAT) & SB_DSP_BUSY) != 0)
|
||||
continue;
|
||||
outb(base + SBP_DSP_WRITE, v);
|
||||
return (0);
|
||||
outb(iobase + SBP_DSP_WRITE, v);
|
||||
return 0;
|
||||
}
|
||||
++sberr.wdsp;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a byte from the DSP, using polling.
|
||||
*/
|
||||
int
|
||||
rdsp(u_long base)
|
||||
rdsp(u_short iobase)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 100; --i >= 0; ) {
|
||||
if ((inb(base + SBP_DSP_RSTAT) & SB_DSP_READY) == 0)
|
||||
if ((inb(iobase + SBP_DSP_RSTAT) & SB_DSP_READY) == 0)
|
||||
continue;
|
||||
return (inb(base + SBP_DSP_READ));
|
||||
return inb(iobase + SBP_DSP_READ);
|
||||
}
|
||||
++sberr.rdsp;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -353,20 +304,23 @@ rdsp(u_long base)
|
|||
* Return non-zero if the card isn't detected.
|
||||
*/
|
||||
int
|
||||
sbreset(register u_long base)
|
||||
sbreset(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
register u_short iobase = sc->sc_iobase;
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* See SBK, section 11.3.
|
||||
* We pulse a reset signal into the card.
|
||||
* Gee, what a brilliant hardware design.
|
||||
*/
|
||||
outb(base + SBP_DSP_RESET, 1);
|
||||
outb(iobase + SBP_DSP_RESET, 1);
|
||||
delay(3);
|
||||
outb(base + SBP_DSP_RESET, 0);
|
||||
if (rdsp(base) != SB_MAGIC)
|
||||
return (-1);
|
||||
return (0);
|
||||
outb(iobase + SBP_DSP_RESET, 0);
|
||||
if (rdsp(iobase) != SB_MAGIC)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -380,9 +334,12 @@ sbreset(register u_long base)
|
|||
* they designed this card.
|
||||
*/
|
||||
void
|
||||
sb_spkron(struct sb_softc *sc)
|
||||
sb_spkron(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
(void)wdsp(sc->sc_base, SB_DSP_SPKR_ON);
|
||||
|
||||
(void)wdsp(sc->sc_iobase, SB_DSP_SPKR_ON);
|
||||
/* XXX bogus */
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
@ -390,9 +347,11 @@ sb_spkron(struct sb_softc *sc)
|
|||
* Turn off the speaker; see comment above.
|
||||
*/
|
||||
void
|
||||
sb_spkroff(struct sb_softc *sc)
|
||||
sb_spkroff(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
(void)wdsp(sc->sc_base, SB_DSP_SPKR_OFF);
|
||||
|
||||
(void)wdsp(sc->sc_iobase, SB_DSP_SPKR_OFF);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -400,14 +359,16 @@ sb_spkroff(struct sb_softc *sc)
|
|||
* in high byte, and minor code in low byte.
|
||||
*/
|
||||
int
|
||||
sbversion(register u_long base)
|
||||
sbversion(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
register u_short iobase = sc->sc_iobase;
|
||||
int v;
|
||||
|
||||
if (wdsp(base, SB_DSP_VERSION) < 0)
|
||||
return (0);
|
||||
v = rdsp(base) << 8;
|
||||
v |= rdsp(base);
|
||||
if (wdsp(iobase, SB_DSP_VERSION) < 0)
|
||||
return 0;
|
||||
v = rdsp(iobase) << 8;
|
||||
v |= rdsp(iobase);
|
||||
return ((v >= 0) ? v : 0);
|
||||
}
|
||||
|
||||
|
@ -416,18 +377,22 @@ sbversion(register u_long base)
|
|||
* resumed with sb_contdma().
|
||||
*/
|
||||
void
|
||||
sb_haltdma(struct sb_softc *sc)
|
||||
sb_haltdma(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
|
||||
if (sc->sc_locked)
|
||||
sbreset(sc->sc_base);
|
||||
sbreset(sc);
|
||||
else
|
||||
(void)wdsp(sc->sc_base, SB_DSP_HALT);
|
||||
(void)wdsp(sc->sc_iobase, SB_DSP_HALT);
|
||||
}
|
||||
|
||||
void
|
||||
sb_contdma(struct sb_softc *sc)
|
||||
sb_contdma(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
(void)wdsp(sc->sc_base, SB_DSP_CONT);
|
||||
|
||||
(void)wdsp(sc->sc_iobase, SB_DSP_CONT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -475,7 +440,10 @@ sb_contdma(struct sb_softc *sc)
|
|||
* so isdac indicates output, and !isdac indicates input.
|
||||
*/
|
||||
int
|
||||
sb_srtotc(int sr, int *mode, int isdac)
|
||||
sb_srtotc(sr, mode, isdac)
|
||||
int sr;
|
||||
int *mode;
|
||||
int isdac;
|
||||
{
|
||||
register int tc = 256 - 1000000 / sr;
|
||||
|
||||
|
@ -499,7 +467,7 @@ sb_srtotc(int sr, int *mode, int isdac)
|
|||
tc = SB_ADC_HS_MAX;
|
||||
}
|
||||
}
|
||||
return (tc);
|
||||
return tc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -507,96 +475,112 @@ sb_srtotc(int sr, int *mode, int isdac)
|
|||
* See SBK, section 12.
|
||||
*/
|
||||
int
|
||||
sb_tctosr(int tc)
|
||||
sb_tctosr(tc)
|
||||
int tc;
|
||||
{
|
||||
return (1000000 / (256 - tc));
|
||||
}
|
||||
|
||||
int
|
||||
sb_set_sr(register struct sb_softc *sc, u_long *sr, int isdac)
|
||||
sb_set_sr(sc, sr, isdac)
|
||||
register struct sb_softc *sc;
|
||||
u_long *sr;
|
||||
int isdac;
|
||||
{
|
||||
register int tc;
|
||||
int mode;
|
||||
|
||||
tc = sb_srtotc(*sr, &mode, isdac);
|
||||
if (wdsp(sc->sc_base, SB_DSP_TIMECONST) < 0 ||
|
||||
wdsp(sc->sc_base, tc) < 0)
|
||||
return (-1);
|
||||
if (wdsp(sc->sc_iobase, SB_DSP_TIMECONST) < 0 ||
|
||||
wdsp(sc->sc_iobase, tc) < 0)
|
||||
return -1;
|
||||
|
||||
*sr = sb_tctosr(tc);
|
||||
sc->sc_adacmode = mode;
|
||||
sc->sc_adactc = tc;
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sb_round_sr(u_long sr, int isdac)
|
||||
sb_round_sr(sr, isdac)
|
||||
u_long sr;
|
||||
int isdac;
|
||||
{
|
||||
int mode, tc;
|
||||
|
||||
tc = sb_srtotc(sr, &mode, isdac);
|
||||
return (sb_tctosr(tc));
|
||||
return sb_tctosr(tc);
|
||||
}
|
||||
|
||||
int
|
||||
sb_dma_input(struct sb_softc *sc, void *p, int cc, void (*intr)(), void *arg)
|
||||
sb_dma_input(sc, p, cc, intr, arg)
|
||||
struct sb_softc *sc;
|
||||
void *p;
|
||||
int cc;
|
||||
void (*intr)();
|
||||
void *arg;
|
||||
{
|
||||
register int base;
|
||||
register u_short iobase;
|
||||
|
||||
at_dma(1, p, cc, sc->sc_dmachan);
|
||||
sc->sc_intr = intr;
|
||||
sc->sc_arg = arg;
|
||||
base = sc->sc_base;
|
||||
iobase = sc->sc_iobase;
|
||||
--cc;
|
||||
if (sc->sc_adacmode == SB_ADAC_LS) {
|
||||
if (wdsp(base, SB_DSP_RDMA) < 0 ||
|
||||
wdsp(base, cc) < 0 ||
|
||||
wdsp(base, cc >> 8) < 0) {
|
||||
sbreset(sc->sc_base);
|
||||
return (EIO);
|
||||
if (wdsp(iobase, SB_DSP_RDMA) < 0 ||
|
||||
wdsp(iobase, cc) < 0 ||
|
||||
wdsp(iobase, cc >> 8) < 0) {
|
||||
sbreset(sc);
|
||||
return EIO;
|
||||
}
|
||||
} else {
|
||||
if (wdsp(base, SB_DSP_BLOCKSIZE) < 0 ||
|
||||
wdsp(base, cc) < 0 ||
|
||||
wdsp(base, cc >> 8) < 0 ||
|
||||
wdsp(base, SB_DSP_HS_INPUT) < 0) {
|
||||
sbreset(sc->sc_base);
|
||||
return (EIO);
|
||||
if (wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 ||
|
||||
wdsp(iobase, cc) < 0 ||
|
||||
wdsp(iobase, cc >> 8) < 0 ||
|
||||
wdsp(iobase, SB_DSP_HS_INPUT) < 0) {
|
||||
sbreset(sc);
|
||||
return EIO;
|
||||
}
|
||||
sc->sc_locked = 1;
|
||||
}
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sb_dma_output(struct sb_softc *sc, void *p, int cc, void (*intr)(), void *arg)
|
||||
sb_dma_output(sc, p, cc, intr, arg)
|
||||
struct sb_softc *sc;
|
||||
void *p;
|
||||
int cc;
|
||||
void (*intr)();
|
||||
void *arg;
|
||||
{
|
||||
register int base;
|
||||
register u_short iobase;
|
||||
|
||||
at_dma(0, p, cc, sc->sc_dmachan);
|
||||
sc->sc_intr = intr;
|
||||
sc->sc_arg = arg;
|
||||
base = sc->sc_base;
|
||||
iobase = sc->sc_iobase;
|
||||
--cc;
|
||||
if (sc->sc_adacmode == SB_ADAC_LS) {
|
||||
if (wdsp(base, SB_DSP_WDMA) < 0 ||
|
||||
wdsp(base, cc) < 0 ||
|
||||
wdsp(base, cc >> 8) < 0) {
|
||||
sbreset(sc->sc_base);
|
||||
return (EIO);
|
||||
if (wdsp(iobase, SB_DSP_WDMA) < 0 ||
|
||||
wdsp(iobase, cc) < 0 ||
|
||||
wdsp(iobase, cc >> 8) < 0) {
|
||||
sbreset(sc);
|
||||
return EIO;
|
||||
}
|
||||
} else {
|
||||
if (wdsp(base, SB_DSP_BLOCKSIZE) < 0 ||
|
||||
wdsp(base, cc) < 0 ||
|
||||
wdsp(base, cc >> 8) < 0 ||
|
||||
wdsp(base, SB_DSP_HS_OUTPUT) < 0) {
|
||||
sbreset(sc->sc_base);
|
||||
return (EIO);
|
||||
if (wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 ||
|
||||
wdsp(iobase, cc) < 0 ||
|
||||
wdsp(iobase, cc >> 8) < 0 ||
|
||||
wdsp(iobase, SB_DSP_HS_OUTPUT) < 0) {
|
||||
sbreset(sc);
|
||||
return EIO;
|
||||
}
|
||||
sc->sc_locked = 1;
|
||||
}
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -606,28 +590,23 @@ sb_dma_output(struct sb_softc *sc, void *p, int cc, void (*intr)(), void *arg)
|
|||
* completion of a dma reception. The three modes are mutually
|
||||
* exclusive so we know a priori which event has occurred.
|
||||
*/
|
||||
#ifdef NEWCONFIG
|
||||
int
|
||||
sbintr(struct sb_softc *sc)
|
||||
sbintr(unit)
|
||||
int unit;
|
||||
{
|
||||
#else
|
||||
int
|
||||
sbintr(int unit)
|
||||
{
|
||||
register struct sb_softc *sc = &sb_softcs[UNIT(unit)];
|
||||
#endif
|
||||
register struct sb_softc *sc = sbcd.cd_devs[SBUNIT(unit)];
|
||||
|
||||
sc->sc_locked = 0;
|
||||
/* clear interrupt */
|
||||
inb(sc->sc_base + SBP_DSP_RSTAT);
|
||||
inb(sc->sc_iobase + SBP_DSP_RSTAT);
|
||||
if (sc->sc_mintr != 0) {
|
||||
int c = rdsp(sc->sc_base);
|
||||
int c = rdsp(sc->sc_iobase);
|
||||
(*sc->sc_mintr)(sc->sc_arg, c);
|
||||
} else if(sc->sc_intr != 0) {
|
||||
} else if (sc->sc_intr != 0)
|
||||
(*sc->sc_intr)(sc->sc_arg);
|
||||
} else
|
||||
return (0);
|
||||
return (1);
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -636,17 +615,19 @@ sbintr(int unit)
|
|||
* which allows only midi I/O; the card must be reset
|
||||
* to leave this mode. Unfortunately, the card does not
|
||||
* use transmit interrupts, so bytes must be output
|
||||
|
||||
|
||||
* using polling. To keep the polling overhead to a
|
||||
* minimum, output should be driven off a timer.
|
||||
* This is a little tricky since only 320us separate
|
||||
* consecutive midi bytes.
|
||||
*/
|
||||
void
|
||||
sb_set_midi_mode(struct sb_softc *sc, void (*intr)(), void *arg)
|
||||
sb_set_midi_mode(sc, intr, arg)
|
||||
struct sb_softc *sc;
|
||||
void (*intr)();
|
||||
void *arg;
|
||||
{
|
||||
wdsp(sc->sc_base, SB_MIDI_UART_INTR);
|
||||
|
||||
wdsp(sc->sc_iobase, SB_MIDI_UART_INTR);
|
||||
sc->sc_mintr = intr;
|
||||
sc->sc_intr = 0;
|
||||
sc->sc_arg = arg;
|
||||
|
@ -656,9 +637,11 @@ sb_set_midi_mode(struct sb_softc *sc, void (*intr)(), void *arg)
|
|||
* Write a byte to the midi port, when in midi uart mode.
|
||||
*/
|
||||
void
|
||||
sb_midi_output(struct sb_softc *sc, int v)
|
||||
sb_midi_output(sc, v)
|
||||
struct sb_softc *sc;
|
||||
int v;
|
||||
{
|
||||
if (wdsp(sc->sc_base, v) < 0)
|
||||
|
||||
if (wdsp(sc->sc_iobase, v) < 0)
|
||||
++sberr.wmidi;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* From: Header: sbreg.h,v 1.3 93/07/18 14:07:28 mccanne Exp (LBL)
|
||||
* $Id: sbreg.h,v 1.1 1994/01/09 19:35:10 cgd Exp $
|
||||
* $Id: sbreg.h,v 1.2 1994/03/29 04:36:28 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -141,7 +141,7 @@
|
|||
*/
|
||||
#define SB_IRQ_VALID(mask) ((mask) & 0x00ac) /* IRQ 2,3,5,7 */
|
||||
#define SB_DRQ_VALID(chan) ((chan) == 1)
|
||||
#define SB_BASE_VALID(chan) ((base) == 0x220 || (base) == 0x240)
|
||||
#define SB_BASE_VALID(base) ((base) == 0x220 || (base) == 0x240)
|
||||
|
||||
#define SB_INPUT_RATE 0
|
||||
#define SB_OUTPUT_RATE 1
|
||||
|
|
|
@ -35,14 +35,11 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
|
||||
* $Id: wd.c,v 1.73 1994/03/12 22:36:40 mycroft Exp $
|
||||
* $Id: wd.c,v 1.74 1994/03/29 04:36:30 mycroft Exp $
|
||||
*/
|
||||
|
||||
#define INSTRUMENT /* instrumentation stuff by Brad Parker */
|
||||
|
||||
#include "wd.h"
|
||||
#if NWDC > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dkbad.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -68,7 +65,10 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#ifndef NEWCONFIG
|
||||
#include <i386/isa/isa_device.h>
|
||||
#endif
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/wdreg.h>
|
||||
|
||||
|
@ -111,8 +111,7 @@ struct wd_softc {
|
|||
long sc_mbcount; /* total byte count left */
|
||||
short sc_skip; /* blocks already transferred */
|
||||
short sc_mskip; /* blocks already transferred for multi */
|
||||
char sc_unit; /* physical unit number */
|
||||
char sc_lunit; /* logical unit number */
|
||||
char sc_drive; /* physical unit number */
|
||||
char sc_state; /* control state */
|
||||
|
||||
u_long sc_copenpart; /* character units open on this drive */
|
||||
|
@ -128,7 +127,7 @@ struct wd_softc {
|
|||
struct disklabel sc_label; /* device configuration data */
|
||||
struct cpu_disklabel sc_cpulabel;
|
||||
long sc_badsect[127]; /* 126 plus trailing -1 marker */
|
||||
} *wd_softc[NWD];
|
||||
};
|
||||
|
||||
struct wdc_softc {
|
||||
struct device sc_dev;
|
||||
|
@ -141,16 +140,17 @@ struct wdc_softc {
|
|||
u_char sc_error; /* copy of error register */
|
||||
u_short sc_iobase; /* i/o port base */
|
||||
int sc_timeout; /* timeout counter */
|
||||
} wdc_softc[NWDC];
|
||||
|
||||
int wdcprobe(), wdcattach(), wdprobe(), wdattach(), wdintr();
|
||||
|
||||
struct isa_driver wdcdriver = {
|
||||
wdcprobe, wdcattach, "wdc",
|
||||
};
|
||||
|
||||
struct isa_driver wddriver = {
|
||||
wdprobe, wdattach, "wd",
|
||||
int wdcprobe(), wdprobe(), wdintr();
|
||||
void wdcattach(), wdattach();
|
||||
|
||||
struct cfdriver wdccd = {
|
||||
NULL, "wdc", wdcprobe, wdcattach, DV_DULL, sizeof(struct wd_softc)
|
||||
};
|
||||
|
||||
struct cfdriver wdcd = {
|
||||
NULL, "wd", wdprobe, wdattach, DV_DISK, sizeof(struct wd_softc)
|
||||
};
|
||||
|
||||
void wdfinish __P((struct wd_softc *, struct buf *));
|
||||
|
@ -176,22 +176,16 @@ int wdcwait __P((struct wdc_softc *, int));
|
|||
* Probe for controller.
|
||||
*/
|
||||
int
|
||||
wdcprobe(dev)
|
||||
struct isa_device *dev;
|
||||
wdcprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct wdc_softc *wdc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct wd_softc *wd;
|
||||
struct wdc_softc *wdc;
|
||||
u_short iobase;
|
||||
|
||||
if (dev->id_unit >= NWDC)
|
||||
return 0;
|
||||
wdc = &wdc_softc[dev->id_unit];
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(wdc->sc_dev.dv_xname, "%s%d", wdcdriver.name, dev->id_unit);
|
||||
wdc->sc_dev.dv_unit = dev->id_unit;
|
||||
|
||||
wdc->sc_iobase = iobase = dev->id_iobase;
|
||||
wdc->sc_iobase = iobase = ia->ia_iobase;
|
||||
|
||||
/* Check if we have registers that work. */
|
||||
outb(iobase+wd_error, 0x5a); /* Error register not writable. */
|
||||
|
@ -210,8 +204,8 @@ wdcprobe(dev)
|
|||
*/
|
||||
wd = (void *)malloc(sizeof(struct wd_softc), M_TEMP, M_NOWAIT);
|
||||
bzero(wd, sizeof(struct wd_softc));
|
||||
wd->sc_unit = 0;
|
||||
wd->sc_lunit = 0;
|
||||
wd->sc_drive = 0;
|
||||
wd->sc_dev.dv_unit = 0;
|
||||
wd->sc_dev.dv_parent = (void *)wdc;
|
||||
|
||||
/* Execute a controller only command. */
|
||||
|
@ -219,76 +213,89 @@ wdcprobe(dev)
|
|||
wait_for_unbusy(wdc) != 0)
|
||||
goto lose;
|
||||
|
||||
wdctimeout(wdc);
|
||||
|
||||
free(wd, M_TEMP);
|
||||
return 8;
|
||||
ia->ia_iosize = 8;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
|
||||
lose:
|
||||
free(wd, M_TEMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
wdcattach(dev)
|
||||
struct isa_device *dev;
|
||||
{
|
||||
struct wdc_attach_args {
|
||||
int wa_drive;
|
||||
};
|
||||
|
||||
int
|
||||
wdprint(aux, wdc)
|
||||
void *aux;
|
||||
char *wdc;
|
||||
{
|
||||
struct wdc_attach_args *wa = aux;
|
||||
|
||||
if (!wdc)
|
||||
printf(" drive %d", wa->wa_drive);
|
||||
return QUIET;
|
||||
}
|
||||
|
||||
void
|
||||
wdcattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct wdc_softc *wdc = (void *)self;
|
||||
struct wdc_attach_args wa;
|
||||
|
||||
wdctimeout(wdc);
|
||||
printf("\n");
|
||||
|
||||
for (wa.wa_drive = 0; wa.wa_drive < 2; wa.wa_drive++)
|
||||
(void)config_found(self, &wa, wdprint);
|
||||
}
|
||||
|
||||
int
|
||||
wdprobe(dev)
|
||||
struct isa_device *dev;
|
||||
wdprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct wd_softc *wd = (void *)self;
|
||||
struct cfdata *cf = wd->sc_dev.dv_cfdata;
|
||||
struct wdc_attach_args *wa = aux;
|
||||
int drive = wa->wa_drive;
|
||||
#ifdef NEWCONFIG
|
||||
|
||||
#define cf_drive cf_loc[0]
|
||||
if (cf->cf_drive != -1 && cf->cf_drive != drive)
|
||||
return 0;
|
||||
#undef cf_drive
|
||||
#else
|
||||
struct isa_device *id = (void *)cf->cf_loc;
|
||||
|
||||
if (id->id_physid != -1 && id->id_physid != drive)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
wd->sc_drive = drive;
|
||||
|
||||
if (wdgetctlr(wd) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for the controller too. Attach each drive if possible.
|
||||
*/
|
||||
int
|
||||
wdattach(dev)
|
||||
struct isa_device *dev;
|
||||
void
|
||||
wdattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
int lunit;
|
||||
struct wd_softc *wd;
|
||||
struct wdc_softc *wdc;
|
||||
struct wd_softc *wd = (void *)self;
|
||||
int i, blank;
|
||||
|
||||
lunit = dev->id_unit;
|
||||
if (lunit == -1) {
|
||||
printf("%s: cannot support unit ?\n", wdc->sc_dev.dv_xname);
|
||||
return 0;
|
||||
}
|
||||
if (lunit >= NWD)
|
||||
return 0;
|
||||
|
||||
wdc = &wdc_softc[dev->id_parent->id_unit];
|
||||
|
||||
wd_softc[lunit] = wd =
|
||||
(void *)malloc(sizeof(struct wd_softc), M_TEMP, M_NOWAIT);
|
||||
bzero(wd, sizeof(struct wd_softc));
|
||||
wd->sc_unit = dev->id_physid;
|
||||
wd->sc_lunit = lunit;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(wd->sc_dev.dv_xname, "%s%d", wddriver.name, dev->id_unit);
|
||||
wd->sc_dev.dv_unit = dev->id_unit;
|
||||
wd->sc_dev.dv_parent = (void *)wdc;
|
||||
|
||||
if (wdgetctlr(wd) != 0) {
|
||||
wd_softc[lunit] = NULL;
|
||||
free(wd, M_TEMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("%s at %s targ %d: ", wd->sc_dev.dv_xname, wdc->sc_dev.dv_xname,
|
||||
dev->id_physid);
|
||||
if (wd->sc_params.wdp_heads == 0)
|
||||
printf("(unknown size) <");
|
||||
printf(": (unknown size) <");
|
||||
else
|
||||
printf("%dMB %d cyl, %d head, %d sec <",
|
||||
printf(": %dMB %d cyl, %d head, %d sec <",
|
||||
wd->sc_label.d_ncylinders * wd->sc_label.d_secpercyl /
|
||||
(1048576 / DEV_BSIZE),
|
||||
wd->sc_label.d_ncylinders, wd->sc_label.d_ntracks,
|
||||
|
@ -307,8 +314,6 @@ wdattach(dev)
|
|||
blank = 1;
|
||||
}
|
||||
printf(">\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -328,9 +333,9 @@ wdstrategy(bp)
|
|||
int s;
|
||||
|
||||
/* Valid unit, controller, and request? */
|
||||
if (lunit >= NWD || bp->b_blkno < 0 ||
|
||||
if (lunit >= wdcd.cd_ndevs || bp->b_blkno < 0 ||
|
||||
howmany(bp->b_bcount, DEV_BSIZE) >= (1 << NBBY) ||
|
||||
(wd = wd_softc[lunit]) == 0) {
|
||||
(wd = wdcd.cd_devs[lunit]) == 0) {
|
||||
bp->b_error = EINVAL;
|
||||
bp->b_flags |= B_ERROR;
|
||||
goto done;
|
||||
|
@ -431,7 +436,7 @@ wdfinish(wd, bp)
|
|||
struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
|
||||
|
||||
#ifdef INSTRUMENT
|
||||
dk_busy &= ~(1 << wd->sc_unit);
|
||||
dk_busy &= ~(1 << wd->sc_drive);
|
||||
#endif
|
||||
wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR);
|
||||
wdc->sc_q.b_errcnt = 0;
|
||||
|
@ -496,7 +501,7 @@ loop:
|
|||
|
||||
/* Obtain controller and drive information */
|
||||
lunit = WDUNIT(bp->b_dev);
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
|
||||
if (wdc->sc_q.b_errcnt >= WDIORETRIES) {
|
||||
wderror(wd, bp, "hard error");
|
||||
|
@ -621,8 +626,8 @@ loop:
|
|||
|
||||
#ifdef INSTRUMENT
|
||||
if (wd->sc_skip == 0) {
|
||||
dk_busy |= 1 << wd->sc_lunit;
|
||||
dk_wds[wd->sc_lunit] += bp->b_bcount >> 6;
|
||||
dk_busy |= 1 << wd->sc_dev.dv_unit;
|
||||
dk_wds[wd->sc_dev.dv_unit] += bp->b_bcount >> 6;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -631,8 +636,8 @@ loop:
|
|||
int command, count;
|
||||
|
||||
#ifdef INSTRUMENT
|
||||
++dk_seek[wd->sc_lunit];
|
||||
++dk_xfer[wd->sc_lunit];
|
||||
++dk_seek[wd->sc_dev.dv_unit];
|
||||
++dk_xfer[wd->sc_dev.dv_unit];
|
||||
#endif
|
||||
|
||||
#ifdef B_FORMAT
|
||||
|
@ -694,7 +699,7 @@ int
|
|||
wdintr(ctrlr)
|
||||
int ctrlr;
|
||||
{
|
||||
struct wdc_softc *wdc = &wdc_softc[ctrlr];
|
||||
struct wdc_softc *wdc = wdccd.cd_devs[ctrlr];
|
||||
struct wd_softc *wd;
|
||||
struct buf *bp;
|
||||
|
||||
|
@ -707,7 +712,7 @@ wdintr(ctrlr)
|
|||
}
|
||||
|
||||
bp = wdc->sc_q.b_forw->b_actf;
|
||||
wd = wd_softc[WDUNIT(bp->b_dev)];
|
||||
wd = wdcd.cd_devs[WDUNIT(bp->b_dev)];
|
||||
wdc->sc_timeout = 0;
|
||||
|
||||
#ifdef WDDEBUG
|
||||
|
@ -816,9 +821,9 @@ wdopen(dev, flag, fmt, p)
|
|||
char *msg;
|
||||
|
||||
lunit = WDUNIT(dev);
|
||||
if (lunit >= NWD)
|
||||
if (lunit >= wdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
if (wd == 0)
|
||||
return ENXIO;
|
||||
|
||||
|
@ -996,7 +1001,7 @@ wdcommand(wd, cylin, head, sector, count, cmd)
|
|||
|
||||
/* Select drive. */
|
||||
iobase = wdc->sc_iobase;
|
||||
outb(iobase+wd_sdh, WDSD_IBM | (wd->sc_unit << 4) | head);
|
||||
outb(iobase+wd_sdh, WDSD_IBM | (wd->sc_drive << 4) | head);
|
||||
if (cmd == WDCC_DIAGNOSE || cmd == WDCC_IDC)
|
||||
stat = wait_for_unbusy(wdc);
|
||||
else
|
||||
|
@ -1027,7 +1032,7 @@ wdsetctlr(wd)
|
|||
struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
|
||||
|
||||
#ifdef WDDEBUG
|
||||
printf("wd(%d,%d) C%dH%dS%d\n", wd->sc_ctrlr, wd->sc_unit,
|
||||
printf("wd(%d,%d) C%dH%dS%d\n", wd->sc_ctrlr, wd->sc_drive,
|
||||
wd->sc_label.d_ncylinders, wd->sc_label.d_ntracks,
|
||||
wd->sc_label.d_nsectors);
|
||||
#endif
|
||||
|
@ -1119,7 +1124,7 @@ wdclose(dev, flag, fmt)
|
|||
int flag;
|
||||
int fmt;
|
||||
{
|
||||
struct wd_softc *wd = wd_softc[WDUNIT(dev)];
|
||||
struct wd_softc *wd = wdcd.cd_devs[WDUNIT(dev)];
|
||||
int part = WDPART(dev), mask = 1 << part;
|
||||
|
||||
switch (fmt) {
|
||||
|
@ -1144,7 +1149,7 @@ wdioctl(dev, cmd, addr, flag, p)
|
|||
struct proc *p;
|
||||
{
|
||||
int lunit = WDUNIT(dev);
|
||||
struct wd_softc *wd = wd_softc[lunit];
|
||||
struct wd_softc *wd = wdcd.cd_devs[lunit];
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -1269,9 +1274,9 @@ wdsize(dev)
|
|||
int lunit = WDUNIT(dev), part = WDPART(dev);
|
||||
struct wd_softc *wd;
|
||||
|
||||
if (lunit >= NWD)
|
||||
if (lunit >= wdcd.cd_ndevs)
|
||||
return -1;
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
if (wd == 0)
|
||||
return -1;
|
||||
|
||||
|
@ -1319,9 +1324,9 @@ wddump(dev)
|
|||
|
||||
lunit = WDUNIT(dev);
|
||||
/* Check for acceptable drive number. */
|
||||
if (lunit >= NWD)
|
||||
if (lunit >= wdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
/* Was it ever initialized? */
|
||||
if (wd == 0 || wd->sc_state < OPEN || wd->sc_flags & WDF_WRITEPROT)
|
||||
return ENXIO;
|
||||
|
@ -1511,8 +1516,8 @@ wdcunwedge(wdc)
|
|||
(void) wdcreset(wdc);
|
||||
|
||||
/* Schedule recalibrate for all drives on this controller. */
|
||||
for (lunit = 0; lunit < NWD; lunit++) {
|
||||
struct wd_softc *wd = wd_softc[lunit];
|
||||
for (lunit = 0; lunit < wdcd.cd_ndevs; lunit++) {
|
||||
struct wd_softc *wd = wdcd.cd_devs[lunit];
|
||||
if (!wd || (void *)wd->sc_dev.dv_parent != wdc)
|
||||
continue;
|
||||
if (wd->sc_state > RECAL)
|
||||
|
@ -1582,5 +1587,3 @@ wderror(dev, bp, msg)
|
|||
printf("%s: %s: status %b error %b\n", wdc->sc_dev.dv_xname,
|
||||
msg, wdc->sc_status, WDCS_BITS, wdc->sc_error, WDERR_BITS);
|
||||
}
|
||||
|
||||
#endif /* NWDC > 0 */
|
||||
|
|
211
sys/dev/ata/wd.c
211
sys/dev/ata/wd.c
|
@ -35,14 +35,11 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
|
||||
* $Id: wd.c,v 1.73 1994/03/12 22:36:40 mycroft Exp $
|
||||
* $Id: wd.c,v 1.74 1994/03/29 04:36:30 mycroft Exp $
|
||||
*/
|
||||
|
||||
#define INSTRUMENT /* instrumentation stuff by Brad Parker */
|
||||
|
||||
#include "wd.h"
|
||||
#if NWDC > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dkbad.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -68,7 +65,10 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#ifndef NEWCONFIG
|
||||
#include <i386/isa/isa_device.h>
|
||||
#endif
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/wdreg.h>
|
||||
|
||||
|
@ -111,8 +111,7 @@ struct wd_softc {
|
|||
long sc_mbcount; /* total byte count left */
|
||||
short sc_skip; /* blocks already transferred */
|
||||
short sc_mskip; /* blocks already transferred for multi */
|
||||
char sc_unit; /* physical unit number */
|
||||
char sc_lunit; /* logical unit number */
|
||||
char sc_drive; /* physical unit number */
|
||||
char sc_state; /* control state */
|
||||
|
||||
u_long sc_copenpart; /* character units open on this drive */
|
||||
|
@ -128,7 +127,7 @@ struct wd_softc {
|
|||
struct disklabel sc_label; /* device configuration data */
|
||||
struct cpu_disklabel sc_cpulabel;
|
||||
long sc_badsect[127]; /* 126 plus trailing -1 marker */
|
||||
} *wd_softc[NWD];
|
||||
};
|
||||
|
||||
struct wdc_softc {
|
||||
struct device sc_dev;
|
||||
|
@ -141,16 +140,17 @@ struct wdc_softc {
|
|||
u_char sc_error; /* copy of error register */
|
||||
u_short sc_iobase; /* i/o port base */
|
||||
int sc_timeout; /* timeout counter */
|
||||
} wdc_softc[NWDC];
|
||||
|
||||
int wdcprobe(), wdcattach(), wdprobe(), wdattach(), wdintr();
|
||||
|
||||
struct isa_driver wdcdriver = {
|
||||
wdcprobe, wdcattach, "wdc",
|
||||
};
|
||||
|
||||
struct isa_driver wddriver = {
|
||||
wdprobe, wdattach, "wd",
|
||||
int wdcprobe(), wdprobe(), wdintr();
|
||||
void wdcattach(), wdattach();
|
||||
|
||||
struct cfdriver wdccd = {
|
||||
NULL, "wdc", wdcprobe, wdcattach, DV_DULL, sizeof(struct wd_softc)
|
||||
};
|
||||
|
||||
struct cfdriver wdcd = {
|
||||
NULL, "wd", wdprobe, wdattach, DV_DISK, sizeof(struct wd_softc)
|
||||
};
|
||||
|
||||
void wdfinish __P((struct wd_softc *, struct buf *));
|
||||
|
@ -176,22 +176,16 @@ int wdcwait __P((struct wdc_softc *, int));
|
|||
* Probe for controller.
|
||||
*/
|
||||
int
|
||||
wdcprobe(dev)
|
||||
struct isa_device *dev;
|
||||
wdcprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct wdc_softc *wdc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct wd_softc *wd;
|
||||
struct wdc_softc *wdc;
|
||||
u_short iobase;
|
||||
|
||||
if (dev->id_unit >= NWDC)
|
||||
return 0;
|
||||
wdc = &wdc_softc[dev->id_unit];
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(wdc->sc_dev.dv_xname, "%s%d", wdcdriver.name, dev->id_unit);
|
||||
wdc->sc_dev.dv_unit = dev->id_unit;
|
||||
|
||||
wdc->sc_iobase = iobase = dev->id_iobase;
|
||||
wdc->sc_iobase = iobase = ia->ia_iobase;
|
||||
|
||||
/* Check if we have registers that work. */
|
||||
outb(iobase+wd_error, 0x5a); /* Error register not writable. */
|
||||
|
@ -210,8 +204,8 @@ wdcprobe(dev)
|
|||
*/
|
||||
wd = (void *)malloc(sizeof(struct wd_softc), M_TEMP, M_NOWAIT);
|
||||
bzero(wd, sizeof(struct wd_softc));
|
||||
wd->sc_unit = 0;
|
||||
wd->sc_lunit = 0;
|
||||
wd->sc_drive = 0;
|
||||
wd->sc_dev.dv_unit = 0;
|
||||
wd->sc_dev.dv_parent = (void *)wdc;
|
||||
|
||||
/* Execute a controller only command. */
|
||||
|
@ -219,76 +213,89 @@ wdcprobe(dev)
|
|||
wait_for_unbusy(wdc) != 0)
|
||||
goto lose;
|
||||
|
||||
wdctimeout(wdc);
|
||||
|
||||
free(wd, M_TEMP);
|
||||
return 8;
|
||||
ia->ia_iosize = 8;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
|
||||
lose:
|
||||
free(wd, M_TEMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
wdcattach(dev)
|
||||
struct isa_device *dev;
|
||||
{
|
||||
struct wdc_attach_args {
|
||||
int wa_drive;
|
||||
};
|
||||
|
||||
int
|
||||
wdprint(aux, wdc)
|
||||
void *aux;
|
||||
char *wdc;
|
||||
{
|
||||
struct wdc_attach_args *wa = aux;
|
||||
|
||||
if (!wdc)
|
||||
printf(" drive %d", wa->wa_drive);
|
||||
return QUIET;
|
||||
}
|
||||
|
||||
void
|
||||
wdcattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct wdc_softc *wdc = (void *)self;
|
||||
struct wdc_attach_args wa;
|
||||
|
||||
wdctimeout(wdc);
|
||||
printf("\n");
|
||||
|
||||
for (wa.wa_drive = 0; wa.wa_drive < 2; wa.wa_drive++)
|
||||
(void)config_found(self, &wa, wdprint);
|
||||
}
|
||||
|
||||
int
|
||||
wdprobe(dev)
|
||||
struct isa_device *dev;
|
||||
wdprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct wd_softc *wd = (void *)self;
|
||||
struct cfdata *cf = wd->sc_dev.dv_cfdata;
|
||||
struct wdc_attach_args *wa = aux;
|
||||
int drive = wa->wa_drive;
|
||||
#ifdef NEWCONFIG
|
||||
|
||||
#define cf_drive cf_loc[0]
|
||||
if (cf->cf_drive != -1 && cf->cf_drive != drive)
|
||||
return 0;
|
||||
#undef cf_drive
|
||||
#else
|
||||
struct isa_device *id = (void *)cf->cf_loc;
|
||||
|
||||
if (id->id_physid != -1 && id->id_physid != drive)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
wd->sc_drive = drive;
|
||||
|
||||
if (wdgetctlr(wd) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for the controller too. Attach each drive if possible.
|
||||
*/
|
||||
int
|
||||
wdattach(dev)
|
||||
struct isa_device *dev;
|
||||
void
|
||||
wdattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
int lunit;
|
||||
struct wd_softc *wd;
|
||||
struct wdc_softc *wdc;
|
||||
struct wd_softc *wd = (void *)self;
|
||||
int i, blank;
|
||||
|
||||
lunit = dev->id_unit;
|
||||
if (lunit == -1) {
|
||||
printf("%s: cannot support unit ?\n", wdc->sc_dev.dv_xname);
|
||||
return 0;
|
||||
}
|
||||
if (lunit >= NWD)
|
||||
return 0;
|
||||
|
||||
wdc = &wdc_softc[dev->id_parent->id_unit];
|
||||
|
||||
wd_softc[lunit] = wd =
|
||||
(void *)malloc(sizeof(struct wd_softc), M_TEMP, M_NOWAIT);
|
||||
bzero(wd, sizeof(struct wd_softc));
|
||||
wd->sc_unit = dev->id_physid;
|
||||
wd->sc_lunit = lunit;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(wd->sc_dev.dv_xname, "%s%d", wddriver.name, dev->id_unit);
|
||||
wd->sc_dev.dv_unit = dev->id_unit;
|
||||
wd->sc_dev.dv_parent = (void *)wdc;
|
||||
|
||||
if (wdgetctlr(wd) != 0) {
|
||||
wd_softc[lunit] = NULL;
|
||||
free(wd, M_TEMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("%s at %s targ %d: ", wd->sc_dev.dv_xname, wdc->sc_dev.dv_xname,
|
||||
dev->id_physid);
|
||||
if (wd->sc_params.wdp_heads == 0)
|
||||
printf("(unknown size) <");
|
||||
printf(": (unknown size) <");
|
||||
else
|
||||
printf("%dMB %d cyl, %d head, %d sec <",
|
||||
printf(": %dMB %d cyl, %d head, %d sec <",
|
||||
wd->sc_label.d_ncylinders * wd->sc_label.d_secpercyl /
|
||||
(1048576 / DEV_BSIZE),
|
||||
wd->sc_label.d_ncylinders, wd->sc_label.d_ntracks,
|
||||
|
@ -307,8 +314,6 @@ wdattach(dev)
|
|||
blank = 1;
|
||||
}
|
||||
printf(">\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -328,9 +333,9 @@ wdstrategy(bp)
|
|||
int s;
|
||||
|
||||
/* Valid unit, controller, and request? */
|
||||
if (lunit >= NWD || bp->b_blkno < 0 ||
|
||||
if (lunit >= wdcd.cd_ndevs || bp->b_blkno < 0 ||
|
||||
howmany(bp->b_bcount, DEV_BSIZE) >= (1 << NBBY) ||
|
||||
(wd = wd_softc[lunit]) == 0) {
|
||||
(wd = wdcd.cd_devs[lunit]) == 0) {
|
||||
bp->b_error = EINVAL;
|
||||
bp->b_flags |= B_ERROR;
|
||||
goto done;
|
||||
|
@ -431,7 +436,7 @@ wdfinish(wd, bp)
|
|||
struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
|
||||
|
||||
#ifdef INSTRUMENT
|
||||
dk_busy &= ~(1 << wd->sc_unit);
|
||||
dk_busy &= ~(1 << wd->sc_drive);
|
||||
#endif
|
||||
wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR);
|
||||
wdc->sc_q.b_errcnt = 0;
|
||||
|
@ -496,7 +501,7 @@ loop:
|
|||
|
||||
/* Obtain controller and drive information */
|
||||
lunit = WDUNIT(bp->b_dev);
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
|
||||
if (wdc->sc_q.b_errcnt >= WDIORETRIES) {
|
||||
wderror(wd, bp, "hard error");
|
||||
|
@ -621,8 +626,8 @@ loop:
|
|||
|
||||
#ifdef INSTRUMENT
|
||||
if (wd->sc_skip == 0) {
|
||||
dk_busy |= 1 << wd->sc_lunit;
|
||||
dk_wds[wd->sc_lunit] += bp->b_bcount >> 6;
|
||||
dk_busy |= 1 << wd->sc_dev.dv_unit;
|
||||
dk_wds[wd->sc_dev.dv_unit] += bp->b_bcount >> 6;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -631,8 +636,8 @@ loop:
|
|||
int command, count;
|
||||
|
||||
#ifdef INSTRUMENT
|
||||
++dk_seek[wd->sc_lunit];
|
||||
++dk_xfer[wd->sc_lunit];
|
||||
++dk_seek[wd->sc_dev.dv_unit];
|
||||
++dk_xfer[wd->sc_dev.dv_unit];
|
||||
#endif
|
||||
|
||||
#ifdef B_FORMAT
|
||||
|
@ -694,7 +699,7 @@ int
|
|||
wdintr(ctrlr)
|
||||
int ctrlr;
|
||||
{
|
||||
struct wdc_softc *wdc = &wdc_softc[ctrlr];
|
||||
struct wdc_softc *wdc = wdccd.cd_devs[ctrlr];
|
||||
struct wd_softc *wd;
|
||||
struct buf *bp;
|
||||
|
||||
|
@ -707,7 +712,7 @@ wdintr(ctrlr)
|
|||
}
|
||||
|
||||
bp = wdc->sc_q.b_forw->b_actf;
|
||||
wd = wd_softc[WDUNIT(bp->b_dev)];
|
||||
wd = wdcd.cd_devs[WDUNIT(bp->b_dev)];
|
||||
wdc->sc_timeout = 0;
|
||||
|
||||
#ifdef WDDEBUG
|
||||
|
@ -816,9 +821,9 @@ wdopen(dev, flag, fmt, p)
|
|||
char *msg;
|
||||
|
||||
lunit = WDUNIT(dev);
|
||||
if (lunit >= NWD)
|
||||
if (lunit >= wdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
if (wd == 0)
|
||||
return ENXIO;
|
||||
|
||||
|
@ -996,7 +1001,7 @@ wdcommand(wd, cylin, head, sector, count, cmd)
|
|||
|
||||
/* Select drive. */
|
||||
iobase = wdc->sc_iobase;
|
||||
outb(iobase+wd_sdh, WDSD_IBM | (wd->sc_unit << 4) | head);
|
||||
outb(iobase+wd_sdh, WDSD_IBM | (wd->sc_drive << 4) | head);
|
||||
if (cmd == WDCC_DIAGNOSE || cmd == WDCC_IDC)
|
||||
stat = wait_for_unbusy(wdc);
|
||||
else
|
||||
|
@ -1027,7 +1032,7 @@ wdsetctlr(wd)
|
|||
struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
|
||||
|
||||
#ifdef WDDEBUG
|
||||
printf("wd(%d,%d) C%dH%dS%d\n", wd->sc_ctrlr, wd->sc_unit,
|
||||
printf("wd(%d,%d) C%dH%dS%d\n", wd->sc_ctrlr, wd->sc_drive,
|
||||
wd->sc_label.d_ncylinders, wd->sc_label.d_ntracks,
|
||||
wd->sc_label.d_nsectors);
|
||||
#endif
|
||||
|
@ -1119,7 +1124,7 @@ wdclose(dev, flag, fmt)
|
|||
int flag;
|
||||
int fmt;
|
||||
{
|
||||
struct wd_softc *wd = wd_softc[WDUNIT(dev)];
|
||||
struct wd_softc *wd = wdcd.cd_devs[WDUNIT(dev)];
|
||||
int part = WDPART(dev), mask = 1 << part;
|
||||
|
||||
switch (fmt) {
|
||||
|
@ -1144,7 +1149,7 @@ wdioctl(dev, cmd, addr, flag, p)
|
|||
struct proc *p;
|
||||
{
|
||||
int lunit = WDUNIT(dev);
|
||||
struct wd_softc *wd = wd_softc[lunit];
|
||||
struct wd_softc *wd = wdcd.cd_devs[lunit];
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -1269,9 +1274,9 @@ wdsize(dev)
|
|||
int lunit = WDUNIT(dev), part = WDPART(dev);
|
||||
struct wd_softc *wd;
|
||||
|
||||
if (lunit >= NWD)
|
||||
if (lunit >= wdcd.cd_ndevs)
|
||||
return -1;
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
if (wd == 0)
|
||||
return -1;
|
||||
|
||||
|
@ -1319,9 +1324,9 @@ wddump(dev)
|
|||
|
||||
lunit = WDUNIT(dev);
|
||||
/* Check for acceptable drive number. */
|
||||
if (lunit >= NWD)
|
||||
if (lunit >= wdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
/* Was it ever initialized? */
|
||||
if (wd == 0 || wd->sc_state < OPEN || wd->sc_flags & WDF_WRITEPROT)
|
||||
return ENXIO;
|
||||
|
@ -1511,8 +1516,8 @@ wdcunwedge(wdc)
|
|||
(void) wdcreset(wdc);
|
||||
|
||||
/* Schedule recalibrate for all drives on this controller. */
|
||||
for (lunit = 0; lunit < NWD; lunit++) {
|
||||
struct wd_softc *wd = wd_softc[lunit];
|
||||
for (lunit = 0; lunit < wdcd.cd_ndevs; lunit++) {
|
||||
struct wd_softc *wd = wdcd.cd_devs[lunit];
|
||||
if (!wd || (void *)wd->sc_dev.dv_parent != wdc)
|
||||
continue;
|
||||
if (wd->sc_state > RECAL)
|
||||
|
@ -1582,5 +1587,3 @@ wderror(dev, bp, msg)
|
|||
printf("%s: %s: status %b error %b\n", wdc->sc_dev.dv_xname,
|
||||
msg, wdc->sc_status, WDCS_BITS, wdc->sc_error, WDERR_BITS);
|
||||
}
|
||||
|
||||
#endif /* NWDC > 0 */
|
||||
|
|
133
sys/dev/ic/com.c
133
sys/dev/ic/com.c
|
@ -32,7 +32,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
|
||||
* $Id: com.c,v 1.28 1994/03/25 04:38:01 mycroft Exp $
|
||||
* $Id: com.c,v 1.29 1994/03/29 04:35:44 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -40,7 +40,6 @@
|
|||
* uses National Semiconductor NS16450/NS16550AF UART
|
||||
*/
|
||||
#include "com.h"
|
||||
#include "ast.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -60,7 +59,7 @@
|
|||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/comreg.h>
|
||||
#include <i386/isa/ic/ns16550.h>
|
||||
|
||||
|
@ -69,7 +68,7 @@ struct com_softc {
|
|||
|
||||
u_short sc_iobase;
|
||||
u_char sc_hwflags;
|
||||
#define COM_HW_MULTI 0x01
|
||||
#define COM_HW_NOIEN 0x01
|
||||
#define COM_HW_FIFO 0x02
|
||||
#define COM_HW_CONSOLE 0x40
|
||||
u_char sc_swflags;
|
||||
|
@ -78,20 +77,20 @@ struct com_softc {
|
|||
#define COM_SW_CRTSCTS 0x04
|
||||
#define COM_SW_MDMBUF 0x08
|
||||
u_char sc_msr, sc_mcr;
|
||||
} com_softc[NCOM];
|
||||
};
|
||||
/* XXXX should be in com_softc, but not ready for that yet */
|
||||
struct tty *com_tty[NCOM];
|
||||
|
||||
int comprobe __P((struct isa_device *));
|
||||
int comattach __P((struct isa_device *));
|
||||
int comprobe();
|
||||
void comattach();
|
||||
int comopen __P((dev_t, int, int, struct proc *));
|
||||
int comclose __P((dev_t, int, int, struct proc *));
|
||||
int comintr __P((int));
|
||||
int comparam __P((struct tty *, struct termios *));
|
||||
void comstart __P((struct tty *));
|
||||
|
||||
struct isa_driver comdriver = {
|
||||
comprobe, comattach, "com"
|
||||
struct cfdriver comcd = {
|
||||
NULL, "com", comprobe, comattach, DV_TTY, sizeof(struct com_softc)
|
||||
};
|
||||
|
||||
int comdefaultrate = TTYDEF_SPEED;
|
||||
|
@ -157,65 +156,39 @@ comprobe1(iobase)
|
|||
}
|
||||
|
||||
int
|
||||
comprobe(dev)
|
||||
struct isa_device *dev;
|
||||
comprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[dev->id_unit];
|
||||
u_short iobase = dev->id_iobase;
|
||||
|
||||
if (dev->id_parent) {
|
||||
if (iobase == 0) {
|
||||
/*
|
||||
* For multiport cards, the iobase may be left
|
||||
* unspecified (zero) for slave ports. In
|
||||
* that case we calculate it from the master
|
||||
* (parent) iobase setting and the slave port
|
||||
* number (physid).
|
||||
*/
|
||||
iobase = dev->id_iobase =
|
||||
dev->id_parent->id_iobase + (8 * dev->id_physid);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", comdriver.name, dev->id_unit);
|
||||
sc->sc_dev.dv_unit = dev->id_unit;
|
||||
struct com_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
|
||||
if (!comprobe1(iobase))
|
||||
return 0;
|
||||
|
||||
return COM_NPORTS;
|
||||
ia->ia_iosize = COM_NPORTS;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
comattach(dev)
|
||||
struct isa_device *dev;
|
||||
void
|
||||
comattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
int unit = dev->id_unit;
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
u_short iobase = dev->id_iobase;
|
||||
struct com_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct cfdata *cf = sc->sc_dev.dv_cfdata;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
struct tty *tp;
|
||||
|
||||
if (unit == comconsole)
|
||||
delay(1000);
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_hwflags = 0;
|
||||
sc->sc_hwflags = cf->cf_flags & COM_HW_NOIEN;
|
||||
sc->sc_swflags = 0;
|
||||
|
||||
printf("%s: ", sc->sc_dev.dv_xname);
|
||||
|
||||
printf("%s", sc->sc_dev.dv_xname);
|
||||
#if NAST > 0
|
||||
if (dev->id_parent) {
|
||||
printf(" at 0x%x %s%d slave %d",
|
||||
dev->id_iobase, dev->id_parent->id_driver->name,
|
||||
dev->id_parent->id_unit, dev->id_physid);
|
||||
astslave(dev);
|
||||
sc->sc_hwflags |= COM_HW_MULTI;
|
||||
}
|
||||
#endif
|
||||
printf(": ");
|
||||
if (sc->sc_dev.dv_unit == comconsole)
|
||||
delay(1000);
|
||||
|
||||
/* look for a NS 16550AF UART with FIFOs */
|
||||
outb(iobase + com_fifo,
|
||||
|
@ -224,11 +197,11 @@ comattach(dev)
|
|||
if ((inb(iobase + com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK)
|
||||
if ((inb(iobase + com_fifo) & FIFO_TRIGGER_14) == FIFO_TRIGGER_14) {
|
||||
sc->sc_hwflags |= COM_HW_FIFO;
|
||||
printf("ns16550a, working fifo\n");
|
||||
printf(": ns16550a, working fifo\n");
|
||||
} else
|
||||
printf("ns82550 or ns16550, broken fifo\n");
|
||||
printf(": ns82550 or ns16550, broken fifo\n");
|
||||
else
|
||||
printf("ns82450 or ns16450, no fifo\n");
|
||||
printf(": ns82450 or ns16450, no fifo\n");
|
||||
outb(iobase + com_fifo, 0);
|
||||
|
||||
/* disable interrupts */
|
||||
|
@ -255,11 +228,11 @@ comattach(dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Need to reset baud rate, etc. of next print so reset comconsinit.
|
||||
* Also make sure console is always "hardwired".
|
||||
*/
|
||||
if (unit == comconsole) {
|
||||
if (sc->sc_dev.dv_unit == comconsole) {
|
||||
/*
|
||||
* Need to reset baud rate, etc. of next print so reset
|
||||
* comconsinit. Also make sure console is always "hardwired".
|
||||
*/
|
||||
comconsinit = 0;
|
||||
sc->sc_hwflags |= COM_HW_CONSOLE;
|
||||
sc->sc_swflags |= COM_SW_SOFTCAR;
|
||||
|
@ -279,10 +252,10 @@ comopen(dev, flag, mode, p)
|
|||
int s;
|
||||
int error = 0;
|
||||
|
||||
if (unit >= NCOM)
|
||||
if (unit >= comcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &com_softc[unit];
|
||||
if (!sc->sc_iobase)
|
||||
sc = comcd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
s = spltty();
|
||||
|
@ -322,7 +295,7 @@ comopen(dev, flag, mode, p)
|
|||
(void) inb(iobase + com_data);
|
||||
/* you turn me on, baby */
|
||||
sc->sc_mcr = MCR_DTR | MCR_RTS;
|
||||
if (!(sc->sc_hwflags & COM_HW_MULTI))
|
||||
if (!(sc->sc_hwflags & COM_HW_NOIEN))
|
||||
sc->sc_mcr |= MCR_IENABLE;
|
||||
outb(iobase + com_mcr, sc->sc_mcr);
|
||||
outb(iobase + com_ier,
|
||||
|
@ -365,7 +338,7 @@ comclose(dev, flag, mode, p)
|
|||
struct proc *p;
|
||||
{
|
||||
int unit = COMUNIT(dev);
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
struct com_softc *sc = comcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct tty *tp = com_tty[unit];
|
||||
|
||||
|
@ -436,7 +409,7 @@ comioctl(dev, cmd, data, flag, p)
|
|||
struct proc *p;
|
||||
{
|
||||
int unit = COMUNIT(dev);
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
struct com_softc *sc = comcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct tty *tp = com_tty[unit];
|
||||
int error;
|
||||
|
@ -540,7 +513,7 @@ comparam(tp, t)
|
|||
struct tty *tp;
|
||||
struct termios *t;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[COMUNIT(tp->t_dev)];
|
||||
struct com_softc *sc = comcd.cd_devs[COMUNIT(tp->t_dev)];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
int ospeed = comspeed(t->c_ospeed);
|
||||
u_char cfcr;
|
||||
|
@ -635,7 +608,7 @@ void
|
|||
comstart(tp)
|
||||
struct tty *tp;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[COMUNIT(tp->t_dev)];
|
||||
struct com_softc *sc = comcd.cd_devs[COMUNIT(tp->t_dev)];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
int s;
|
||||
|
||||
|
@ -749,7 +722,7 @@ int
|
|||
comintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
struct com_softc *sc = comcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct tty *tp;
|
||||
u_char code;
|
||||
|
@ -807,7 +780,6 @@ comintr(unit)
|
|||
comcnprobe(cp)
|
||||
struct consdev *cp;
|
||||
{
|
||||
int unit = CONUNIT;
|
||||
|
||||
if (!comprobe1(CONADDR)) {
|
||||
cp->cn_pri = CN_DEAD;
|
||||
|
@ -819,10 +791,8 @@ comcnprobe(cp)
|
|||
if (cdevsw[commajor].d_open == comopen)
|
||||
break;
|
||||
|
||||
com_softc[unit].sc_iobase = CONADDR;
|
||||
|
||||
/* initialize required fields */
|
||||
cp->cn_dev = makedev(commajor, unit);
|
||||
cp->cn_dev = makedev(commajor, CONUNIT);
|
||||
#ifdef COMCONSOLE
|
||||
cp->cn_pri = CN_REMOTE; /* Force a serial port console */
|
||||
#else
|
||||
|
@ -833,10 +803,9 @@ comcnprobe(cp)
|
|||
comcninit(cp)
|
||||
struct consdev *cp;
|
||||
{
|
||||
int unit = CONUNIT;
|
||||
|
||||
cominit(unit, comdefaultrate);
|
||||
comconsole = unit;
|
||||
cominit(CONUNIT, comdefaultrate);
|
||||
comconsole = CONUNIT;
|
||||
comconsinit = 0;
|
||||
}
|
||||
|
||||
|
@ -844,7 +813,7 @@ cominit(unit, rate)
|
|||
int unit, rate;
|
||||
{
|
||||
int s = splhigh();
|
||||
u_short iobase = com_softc[unit].sc_iobase;
|
||||
u_short iobase = CONADDR;
|
||||
u_char stat;
|
||||
|
||||
outb(iobase + com_cfcr, CFCR_DLAB);
|
||||
|
@ -862,7 +831,7 @@ comcngetc(dev)
|
|||
dev_t dev;
|
||||
{
|
||||
int s = splhigh();
|
||||
u_short iobase = com_softc[COMUNIT(dev)].sc_iobase;
|
||||
u_short iobase = CONADDR;
|
||||
u_char stat, c;
|
||||
|
||||
while (((stat = inb(iobase + com_lsr)) & LSR_RXRDY) == 0)
|
||||
|
@ -881,7 +850,7 @@ comcnputc(dev, c)
|
|||
int c;
|
||||
{
|
||||
int s = splhigh();
|
||||
u_short iobase = com_softc[COMUNIT(dev)].sc_iobase;
|
||||
u_short iobase = CONADDR;
|
||||
u_char stat;
|
||||
register int timo;
|
||||
|
||||
|
|
|
@ -46,15 +46,13 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: lpt.c,v 1.14 1994/03/06 17:19:11 mycroft Exp $
|
||||
* $Id: lpt.c,v 1.15 1994/03/29 04:36:08 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Device Driver for AT parallel printer port
|
||||
*/
|
||||
|
||||
#include "lpt.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -70,7 +68,7 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/lptreg.h>
|
||||
|
||||
#define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */
|
||||
|
@ -104,14 +102,14 @@ struct lpt_softc {
|
|||
#define LPT_NOPRIME 0x40 /* don't prime on open */
|
||||
#define LPT_NOINTR 0x80 /* do not use interrupt */
|
||||
u_char sc_control;
|
||||
} lpt_softc[NLPT];
|
||||
};
|
||||
|
||||
int lptprobe __P((struct isa_device *));
|
||||
int lptattach __P((struct isa_device *));
|
||||
int lptprobe();
|
||||
void lptattach();
|
||||
int lptintr __P((int));
|
||||
|
||||
struct isa_driver lptdriver = {
|
||||
lptprobe, lptattach, "lpt"
|
||||
struct cfdriver lptcd = {
|
||||
NULL, "lpt", lptprobe, lptattach, DV_TTY, sizeof(struct lpt_softc)
|
||||
};
|
||||
|
||||
#define LPTUNIT(s) (minor(s) & 0x1f)
|
||||
|
@ -174,10 +172,12 @@ lpt_port_test(port, data, mask)
|
|||
* 3) Set the data and control ports to a value of 0
|
||||
*/
|
||||
int
|
||||
lptprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
lptprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_short port;
|
||||
u_char mask, data;
|
||||
int i;
|
||||
|
@ -226,23 +226,25 @@ lptprobe(isa_dev)
|
|||
outb(iobase + lpt_data, 0);
|
||||
outb(iobase + lpt_control, 0);
|
||||
|
||||
return LPT_NPORTS;
|
||||
ia->ia_iosize = LPT_NPORTS;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
lptattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
lptattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[isa_dev->id_unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
u_short irq = isa_dev->id_irq;
|
||||
struct lpt_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_short irq = ia->ia_irq;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", lptdriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
if (!irq)
|
||||
printf("%s: polled\n", sc->sc_dev.dv_xname);
|
||||
if (irq)
|
||||
printf("\n");
|
||||
else
|
||||
printf(": polled\n");
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_irq = irq;
|
||||
|
@ -266,10 +268,10 @@ lptopen(dev, flag)
|
|||
int error;
|
||||
int spin;
|
||||
|
||||
if (unit >= NLPT)
|
||||
if (unit >= lptcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &lpt_softc[unit];
|
||||
if (!sc->sc_iobase)
|
||||
sc = lptcd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
if (sc->sc_irq == 0 && (flags & LPT_NOINTR) == 0)
|
||||
|
@ -372,7 +374,7 @@ lptclose(dev, flag)
|
|||
int flag;
|
||||
{
|
||||
int unit = LPTUNIT(dev);
|
||||
struct lpt_softc *sc = &lpt_softc[unit];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
|
||||
if (sc->sc_count)
|
||||
|
@ -454,7 +456,7 @@ lptwrite(dev, uio)
|
|||
dev_t dev;
|
||||
struct uio *uio;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[LPTUNIT(dev)];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[LPTUNIT(dev)];
|
||||
size_t n;
|
||||
int error = 0;
|
||||
|
||||
|
@ -483,7 +485,7 @@ int
|
|||
lptintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[unit];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -46,15 +46,13 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: lptvar.h,v 1.14 1994/03/06 17:19:11 mycroft Exp $
|
||||
* $Id: lptvar.h,v 1.15 1994/03/29 04:36:08 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Device Driver for AT parallel printer port
|
||||
*/
|
||||
|
||||
#include "lpt.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -70,7 +68,7 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/lptreg.h>
|
||||
|
||||
#define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */
|
||||
|
@ -104,14 +102,14 @@ struct lpt_softc {
|
|||
#define LPT_NOPRIME 0x40 /* don't prime on open */
|
||||
#define LPT_NOINTR 0x80 /* do not use interrupt */
|
||||
u_char sc_control;
|
||||
} lpt_softc[NLPT];
|
||||
};
|
||||
|
||||
int lptprobe __P((struct isa_device *));
|
||||
int lptattach __P((struct isa_device *));
|
||||
int lptprobe();
|
||||
void lptattach();
|
||||
int lptintr __P((int));
|
||||
|
||||
struct isa_driver lptdriver = {
|
||||
lptprobe, lptattach, "lpt"
|
||||
struct cfdriver lptcd = {
|
||||
NULL, "lpt", lptprobe, lptattach, DV_TTY, sizeof(struct lpt_softc)
|
||||
};
|
||||
|
||||
#define LPTUNIT(s) (minor(s) & 0x1f)
|
||||
|
@ -174,10 +172,12 @@ lpt_port_test(port, data, mask)
|
|||
* 3) Set the data and control ports to a value of 0
|
||||
*/
|
||||
int
|
||||
lptprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
lptprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_short port;
|
||||
u_char mask, data;
|
||||
int i;
|
||||
|
@ -226,23 +226,25 @@ lptprobe(isa_dev)
|
|||
outb(iobase + lpt_data, 0);
|
||||
outb(iobase + lpt_control, 0);
|
||||
|
||||
return LPT_NPORTS;
|
||||
ia->ia_iosize = LPT_NPORTS;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
lptattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
lptattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[isa_dev->id_unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
u_short irq = isa_dev->id_irq;
|
||||
struct lpt_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_short irq = ia->ia_irq;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", lptdriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
if (!irq)
|
||||
printf("%s: polled\n", sc->sc_dev.dv_xname);
|
||||
if (irq)
|
||||
printf("\n");
|
||||
else
|
||||
printf(": polled\n");
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_irq = irq;
|
||||
|
@ -266,10 +268,10 @@ lptopen(dev, flag)
|
|||
int error;
|
||||
int spin;
|
||||
|
||||
if (unit >= NLPT)
|
||||
if (unit >= lptcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &lpt_softc[unit];
|
||||
if (!sc->sc_iobase)
|
||||
sc = lptcd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
if (sc->sc_irq == 0 && (flags & LPT_NOINTR) == 0)
|
||||
|
@ -372,7 +374,7 @@ lptclose(dev, flag)
|
|||
int flag;
|
||||
{
|
||||
int unit = LPTUNIT(dev);
|
||||
struct lpt_softc *sc = &lpt_softc[unit];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
|
||||
if (sc->sc_count)
|
||||
|
@ -454,7 +456,7 @@ lptwrite(dev, uio)
|
|||
dev_t dev;
|
||||
struct uio *uio;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[LPTUNIT(dev)];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[LPTUNIT(dev)];
|
||||
size_t n;
|
||||
int error = 0;
|
||||
|
||||
|
@ -483,7 +485,7 @@ int
|
|||
lptintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[unit];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -5,90 +5,129 @@
|
|||
*
|
||||
* Modified by: Charles Hannum, 3/22/94
|
||||
*
|
||||
* $Id: ast.c,v 1.4 1994/03/23 03:55:24 cgd Exp $
|
||||
* $Id: ast.c,v 1.5 1994/03/29 04:35:37 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include "ast.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/pio.h>
|
||||
|
||||
#ifndef NEWCONFIG
|
||||
#include <i386/isa/isa_device.h>
|
||||
|
||||
int astprobe __P((struct isa_device *));
|
||||
int astattach __P((struct isa_device *));
|
||||
|
||||
struct isa_driver astdriver = {
|
||||
astprobe, astattach, "ast"
|
||||
};
|
||||
#endif
|
||||
#include <i386/isa/isavar.h>
|
||||
|
||||
struct ast_softc {
|
||||
struct device sc_dev;
|
||||
u_short sc_iobase;
|
||||
int sc_alive; /* Mask of slave units attached. */
|
||||
int sc_slaves[8]; /* com device unit numbers. XXX - softc ptrs */
|
||||
} ast_softc[NAST];
|
||||
int sc_alive; /* mask of slave units attached */
|
||||
int sc_slaves[8]; /* com device unit numbers */
|
||||
};
|
||||
|
||||
int astprobe();
|
||||
void astattach();
|
||||
|
||||
struct cfdriver astcd = {
|
||||
NULL, "ast", astprobe, astattach, DV_TTY, sizeof(struct ast_softc)
|
||||
};
|
||||
|
||||
int
|
||||
astprobe(dev)
|
||||
struct isa_device *dev;
|
||||
astprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
/*
|
||||
* Do the normal com probe for the first UART and assume
|
||||
* its presence means there is a multiport board there.
|
||||
* XXX needs more robustness.
|
||||
* XXX Needs more robustness.
|
||||
*/
|
||||
return comprobe1(dev->id_iobase);
|
||||
return comprobe1(ia->ia_iobase);
|
||||
}
|
||||
|
||||
struct ast_attach_args {
|
||||
u_short aa_iobase;
|
||||
int aa_slave;
|
||||
};
|
||||
|
||||
int
|
||||
astattach(dev)
|
||||
struct isa_device *dev;
|
||||
astsubmatch(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ast_softc *sc = &ast_softc[dev->id_unit];
|
||||
u_short iobase = dev->id_iobase;
|
||||
unsigned int x;
|
||||
struct ast_softc *sc = (void *)parent;
|
||||
struct ast_attach_args *aa = aux;
|
||||
struct cfdata *cf = self->dv_cfdata;
|
||||
int found, frobbed = 0;
|
||||
#ifdef NEWCONFIG
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", astdriver.name, dev->id_unit);
|
||||
sc->sc_dev.dv_unit = dev->id_unit;
|
||||
#define cf_slave cf_loc[6]
|
||||
if (cf->cf_slave != -1 && cf->cf_slave != aa->aa_slave)
|
||||
return 0;
|
||||
if (cf->cf_iobase == IOBASEUNK) {
|
||||
frobbed = 1;
|
||||
cf->cf_iobase = aa->aa_iobase;
|
||||
}
|
||||
#undef cf_slave
|
||||
#else
|
||||
struct isa_device *id = (void *)cf->cf_loc;
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
if (id->id_physid != -1 && id->id_physid != aa->aa_slave)
|
||||
return 0;
|
||||
if (id->id_iobase == 0) {
|
||||
frobbed = 1;
|
||||
id->id_iobase = aa->aa_iobase;
|
||||
}
|
||||
#endif
|
||||
found = isasubmatch(parent, self, aux);
|
||||
if (found) {
|
||||
sc->sc_slaves[aa->aa_slave] = cf->cf_unit;
|
||||
sc->sc_alive |= 1 << aa->aa_slave;
|
||||
}
|
||||
/*
|
||||
* If we changed the iobase, we have to set it back now, because it
|
||||
* might be a clone device, and the iobase wouldn't get set properly on
|
||||
* the next iteration.
|
||||
*/
|
||||
#ifdef NEWCONFIG
|
||||
if (frobbed)
|
||||
cf->cf_iobase = IOBASEUNK;
|
||||
#else
|
||||
if (frobbed)
|
||||
id->id_iobase = 0;
|
||||
#endif
|
||||
return found;
|
||||
}
|
||||
|
||||
void
|
||||
astattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ast_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct ast_attach_args aa;
|
||||
|
||||
/*
|
||||
* Enable the master interrupt.
|
||||
*/
|
||||
outb(iobase | 0x1f, 0x80);
|
||||
x = inb(iobase | 0x1f);
|
||||
/*
|
||||
* My guess is this bitmask tells you how many ports are there.
|
||||
* I only have a 4-port board to try (returns 0xf). --roland
|
||||
*
|
||||
* It's also not clear that it would be correct to rely on this, since
|
||||
* there might be an interrupt pending on one of the ports, and thus
|
||||
* its bit wouldn't be set. I think the AST protocol simply does not
|
||||
* support more than 4 ports. - mycroft
|
||||
*/
|
||||
printf("%s: 0x%x\n", sc->sc_dev.dv_xname, x);
|
||||
}
|
||||
sc->sc_iobase = ia->ia_iobase;
|
||||
outb(sc->sc_iobase | 0x1f, 0x80);
|
||||
printf("\n");
|
||||
|
||||
void
|
||||
astslave(dev)
|
||||
struct isa_device *dev;
|
||||
{
|
||||
struct ast_softc *sc = &ast_softc[dev->id_parent->id_unit];
|
||||
|
||||
sc->sc_slaves[dev->id_physid] = dev->id_unit;
|
||||
sc->sc_alive |= 1 << dev->id_physid;
|
||||
for (aa.aa_slave = 0, aa.aa_iobase = sc->sc_iobase;
|
||||
aa.aa_slave < 4;
|
||||
aa.aa_slave++, aa.aa_iobase += 8)
|
||||
config_search(astsubmatch, self, &aa);
|
||||
}
|
||||
|
||||
int
|
||||
astintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct ast_softc *sc = &ast_softc[unit];
|
||||
struct ast_softc *sc = astcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
int alive = sc->sc_alive;
|
||||
int bits;
|
||||
|
@ -100,17 +139,12 @@ astintr(unit)
|
|||
do {
|
||||
#define TRY(n) \
|
||||
if ((bits & (1 << (n))) == 0) \
|
||||
comintr(sc->sc_slaves[n]); /* XXX softc ptr */
|
||||
comintr(sc->sc_slaves[n]);
|
||||
TRY(0);
|
||||
TRY(1);
|
||||
TRY(2);
|
||||
TRY(3);
|
||||
#ifdef notdef
|
||||
TRY(4);
|
||||
TRY(5);
|
||||
TRY(6);
|
||||
TRY(7);
|
||||
#endif
|
||||
#undef TRY
|
||||
bits = inb(iobase | 0x1f) & alive;
|
||||
} while (bits != alive);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
|
||||
* $Id: com.c,v 1.28 1994/03/25 04:38:01 mycroft Exp $
|
||||
* $Id: com.c,v 1.29 1994/03/29 04:35:44 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -40,7 +40,6 @@
|
|||
* uses National Semiconductor NS16450/NS16550AF UART
|
||||
*/
|
||||
#include "com.h"
|
||||
#include "ast.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -60,7 +59,7 @@
|
|||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/comreg.h>
|
||||
#include <i386/isa/ic/ns16550.h>
|
||||
|
||||
|
@ -69,7 +68,7 @@ struct com_softc {
|
|||
|
||||
u_short sc_iobase;
|
||||
u_char sc_hwflags;
|
||||
#define COM_HW_MULTI 0x01
|
||||
#define COM_HW_NOIEN 0x01
|
||||
#define COM_HW_FIFO 0x02
|
||||
#define COM_HW_CONSOLE 0x40
|
||||
u_char sc_swflags;
|
||||
|
@ -78,20 +77,20 @@ struct com_softc {
|
|||
#define COM_SW_CRTSCTS 0x04
|
||||
#define COM_SW_MDMBUF 0x08
|
||||
u_char sc_msr, sc_mcr;
|
||||
} com_softc[NCOM];
|
||||
};
|
||||
/* XXXX should be in com_softc, but not ready for that yet */
|
||||
struct tty *com_tty[NCOM];
|
||||
|
||||
int comprobe __P((struct isa_device *));
|
||||
int comattach __P((struct isa_device *));
|
||||
int comprobe();
|
||||
void comattach();
|
||||
int comopen __P((dev_t, int, int, struct proc *));
|
||||
int comclose __P((dev_t, int, int, struct proc *));
|
||||
int comintr __P((int));
|
||||
int comparam __P((struct tty *, struct termios *));
|
||||
void comstart __P((struct tty *));
|
||||
|
||||
struct isa_driver comdriver = {
|
||||
comprobe, comattach, "com"
|
||||
struct cfdriver comcd = {
|
||||
NULL, "com", comprobe, comattach, DV_TTY, sizeof(struct com_softc)
|
||||
};
|
||||
|
||||
int comdefaultrate = TTYDEF_SPEED;
|
||||
|
@ -157,65 +156,39 @@ comprobe1(iobase)
|
|||
}
|
||||
|
||||
int
|
||||
comprobe(dev)
|
||||
struct isa_device *dev;
|
||||
comprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[dev->id_unit];
|
||||
u_short iobase = dev->id_iobase;
|
||||
|
||||
if (dev->id_parent) {
|
||||
if (iobase == 0) {
|
||||
/*
|
||||
* For multiport cards, the iobase may be left
|
||||
* unspecified (zero) for slave ports. In
|
||||
* that case we calculate it from the master
|
||||
* (parent) iobase setting and the slave port
|
||||
* number (physid).
|
||||
*/
|
||||
iobase = dev->id_iobase =
|
||||
dev->id_parent->id_iobase + (8 * dev->id_physid);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", comdriver.name, dev->id_unit);
|
||||
sc->sc_dev.dv_unit = dev->id_unit;
|
||||
struct com_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
|
||||
if (!comprobe1(iobase))
|
||||
return 0;
|
||||
|
||||
return COM_NPORTS;
|
||||
ia->ia_iosize = COM_NPORTS;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
comattach(dev)
|
||||
struct isa_device *dev;
|
||||
void
|
||||
comattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
int unit = dev->id_unit;
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
u_short iobase = dev->id_iobase;
|
||||
struct com_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct cfdata *cf = sc->sc_dev.dv_cfdata;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
struct tty *tp;
|
||||
|
||||
if (unit == comconsole)
|
||||
delay(1000);
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_hwflags = 0;
|
||||
sc->sc_hwflags = cf->cf_flags & COM_HW_NOIEN;
|
||||
sc->sc_swflags = 0;
|
||||
|
||||
printf("%s: ", sc->sc_dev.dv_xname);
|
||||
|
||||
printf("%s", sc->sc_dev.dv_xname);
|
||||
#if NAST > 0
|
||||
if (dev->id_parent) {
|
||||
printf(" at 0x%x %s%d slave %d",
|
||||
dev->id_iobase, dev->id_parent->id_driver->name,
|
||||
dev->id_parent->id_unit, dev->id_physid);
|
||||
astslave(dev);
|
||||
sc->sc_hwflags |= COM_HW_MULTI;
|
||||
}
|
||||
#endif
|
||||
printf(": ");
|
||||
if (sc->sc_dev.dv_unit == comconsole)
|
||||
delay(1000);
|
||||
|
||||
/* look for a NS 16550AF UART with FIFOs */
|
||||
outb(iobase + com_fifo,
|
||||
|
@ -224,11 +197,11 @@ comattach(dev)
|
|||
if ((inb(iobase + com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK)
|
||||
if ((inb(iobase + com_fifo) & FIFO_TRIGGER_14) == FIFO_TRIGGER_14) {
|
||||
sc->sc_hwflags |= COM_HW_FIFO;
|
||||
printf("ns16550a, working fifo\n");
|
||||
printf(": ns16550a, working fifo\n");
|
||||
} else
|
||||
printf("ns82550 or ns16550, broken fifo\n");
|
||||
printf(": ns82550 or ns16550, broken fifo\n");
|
||||
else
|
||||
printf("ns82450 or ns16450, no fifo\n");
|
||||
printf(": ns82450 or ns16450, no fifo\n");
|
||||
outb(iobase + com_fifo, 0);
|
||||
|
||||
/* disable interrupts */
|
||||
|
@ -255,11 +228,11 @@ comattach(dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Need to reset baud rate, etc. of next print so reset comconsinit.
|
||||
* Also make sure console is always "hardwired".
|
||||
*/
|
||||
if (unit == comconsole) {
|
||||
if (sc->sc_dev.dv_unit == comconsole) {
|
||||
/*
|
||||
* Need to reset baud rate, etc. of next print so reset
|
||||
* comconsinit. Also make sure console is always "hardwired".
|
||||
*/
|
||||
comconsinit = 0;
|
||||
sc->sc_hwflags |= COM_HW_CONSOLE;
|
||||
sc->sc_swflags |= COM_SW_SOFTCAR;
|
||||
|
@ -279,10 +252,10 @@ comopen(dev, flag, mode, p)
|
|||
int s;
|
||||
int error = 0;
|
||||
|
||||
if (unit >= NCOM)
|
||||
if (unit >= comcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &com_softc[unit];
|
||||
if (!sc->sc_iobase)
|
||||
sc = comcd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
s = spltty();
|
||||
|
@ -322,7 +295,7 @@ comopen(dev, flag, mode, p)
|
|||
(void) inb(iobase + com_data);
|
||||
/* you turn me on, baby */
|
||||
sc->sc_mcr = MCR_DTR | MCR_RTS;
|
||||
if (!(sc->sc_hwflags & COM_HW_MULTI))
|
||||
if (!(sc->sc_hwflags & COM_HW_NOIEN))
|
||||
sc->sc_mcr |= MCR_IENABLE;
|
||||
outb(iobase + com_mcr, sc->sc_mcr);
|
||||
outb(iobase + com_ier,
|
||||
|
@ -365,7 +338,7 @@ comclose(dev, flag, mode, p)
|
|||
struct proc *p;
|
||||
{
|
||||
int unit = COMUNIT(dev);
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
struct com_softc *sc = comcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct tty *tp = com_tty[unit];
|
||||
|
||||
|
@ -436,7 +409,7 @@ comioctl(dev, cmd, data, flag, p)
|
|||
struct proc *p;
|
||||
{
|
||||
int unit = COMUNIT(dev);
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
struct com_softc *sc = comcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct tty *tp = com_tty[unit];
|
||||
int error;
|
||||
|
@ -540,7 +513,7 @@ comparam(tp, t)
|
|||
struct tty *tp;
|
||||
struct termios *t;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[COMUNIT(tp->t_dev)];
|
||||
struct com_softc *sc = comcd.cd_devs[COMUNIT(tp->t_dev)];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
int ospeed = comspeed(t->c_ospeed);
|
||||
u_char cfcr;
|
||||
|
@ -635,7 +608,7 @@ void
|
|||
comstart(tp)
|
||||
struct tty *tp;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[COMUNIT(tp->t_dev)];
|
||||
struct com_softc *sc = comcd.cd_devs[COMUNIT(tp->t_dev)];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
int s;
|
||||
|
||||
|
@ -749,7 +722,7 @@ int
|
|||
comintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct com_softc *sc = &com_softc[unit];
|
||||
struct com_softc *sc = comcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct tty *tp;
|
||||
u_char code;
|
||||
|
@ -807,7 +780,6 @@ comintr(unit)
|
|||
comcnprobe(cp)
|
||||
struct consdev *cp;
|
||||
{
|
||||
int unit = CONUNIT;
|
||||
|
||||
if (!comprobe1(CONADDR)) {
|
||||
cp->cn_pri = CN_DEAD;
|
||||
|
@ -819,10 +791,8 @@ comcnprobe(cp)
|
|||
if (cdevsw[commajor].d_open == comopen)
|
||||
break;
|
||||
|
||||
com_softc[unit].sc_iobase = CONADDR;
|
||||
|
||||
/* initialize required fields */
|
||||
cp->cn_dev = makedev(commajor, unit);
|
||||
cp->cn_dev = makedev(commajor, CONUNIT);
|
||||
#ifdef COMCONSOLE
|
||||
cp->cn_pri = CN_REMOTE; /* Force a serial port console */
|
||||
#else
|
||||
|
@ -833,10 +803,9 @@ comcnprobe(cp)
|
|||
comcninit(cp)
|
||||
struct consdev *cp;
|
||||
{
|
||||
int unit = CONUNIT;
|
||||
|
||||
cominit(unit, comdefaultrate);
|
||||
comconsole = unit;
|
||||
cominit(CONUNIT, comdefaultrate);
|
||||
comconsole = CONUNIT;
|
||||
comconsinit = 0;
|
||||
}
|
||||
|
||||
|
@ -844,7 +813,7 @@ cominit(unit, rate)
|
|||
int unit, rate;
|
||||
{
|
||||
int s = splhigh();
|
||||
u_short iobase = com_softc[unit].sc_iobase;
|
||||
u_short iobase = CONADDR;
|
||||
u_char stat;
|
||||
|
||||
outb(iobase + com_cfcr, CFCR_DLAB);
|
||||
|
@ -862,7 +831,7 @@ comcngetc(dev)
|
|||
dev_t dev;
|
||||
{
|
||||
int s = splhigh();
|
||||
u_short iobase = com_softc[COMUNIT(dev)].sc_iobase;
|
||||
u_short iobase = CONADDR;
|
||||
u_char stat, c;
|
||||
|
||||
while (((stat = inb(iobase + com_lsr)) & LSR_RXRDY) == 0)
|
||||
|
@ -881,7 +850,7 @@ comcnputc(dev, c)
|
|||
int c;
|
||||
{
|
||||
int s = splhigh();
|
||||
u_short iobase = com_softc[COMUNIT(dev)].sc_iobase;
|
||||
u_short iobase = CONADDR;
|
||||
u_char stat;
|
||||
register int timo;
|
||||
|
||||
|
|
|
@ -13,10 +13,9 @@
|
|||
* Currently supports the Western Digital/SMC 8003 and 8013 series, the 3Com
|
||||
* 3c503, the NE1000 and NE2000, and a variety of similar clones.
|
||||
*
|
||||
* $Id: if_ed.c,v 1.38 1994/03/08 12:21:19 mycroft Exp $
|
||||
* $Id: if_ed.c,v 1.39 1994/03/29 04:35:47 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include "ed.h"
|
||||
#include "bpfilter.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -55,14 +54,14 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/if_edreg.h>
|
||||
|
||||
/*
|
||||
* ed_softc: per line info and status
|
||||
*/
|
||||
struct ed_softc {
|
||||
struct ed_softc {
|
||||
struct device sc_dev;
|
||||
|
||||
struct arpcom sc_arpcom; /* ethernet common */
|
||||
|
@ -101,10 +100,10 @@ struct ed_softc {
|
|||
u_char rec_page_start; /* first page of RX ring-buffer */
|
||||
u_char rec_page_stop; /* last page of RX ring-buffer */
|
||||
u_char next_packet; /* pointer to next unread RX packet */
|
||||
} ed_softc[NED];
|
||||
};
|
||||
|
||||
int ed_probe __P((struct isa_device *));
|
||||
int ed_attach __P((struct isa_device *));
|
||||
int edprobe();
|
||||
void edattach();
|
||||
int edintr __P((int));
|
||||
int ed_ioctl __P((struct ifnet *, int, caddr_t));
|
||||
int ed_start __P((struct ifnet *));
|
||||
|
@ -131,10 +130,8 @@ struct trailer_header {
|
|||
u_short ether_residual;
|
||||
};
|
||||
|
||||
struct isa_driver eddriver = {
|
||||
ed_probe,
|
||||
ed_attach,
|
||||
"ed"
|
||||
struct cfdriver edcd = {
|
||||
NULL, "ed", edprobe, edattach, DV_IFNET, sizeof(struct ed_softc)
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -171,22 +168,20 @@ static u_short ed_790_intr_mask[] = {
|
|||
* Determine if the device is present.
|
||||
*/
|
||||
int
|
||||
ed_probe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
edprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
|
||||
int nports;
|
||||
struct ed_softc *sc = (void *)self;
|
||||
struct cfdata *cf = sc->sc_dev.dv_cfdata;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", eddriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
if (nports = ed_probe_WD80x3(isa_dev))
|
||||
return nports;
|
||||
if (nports = ed_probe_3Com(isa_dev))
|
||||
return nports;
|
||||
if (nports = ed_probe_Novell(isa_dev))
|
||||
return nports;
|
||||
if (ed_probe_WD80x3(sc, cf, ia))
|
||||
return 1;
|
||||
if (ed_probe_3Com(sc, cf, ia))
|
||||
return 1;
|
||||
if (ed_probe_Novell(sc, cf, ia))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -211,11 +206,11 @@ ed_probe(isa_dev)
|
|||
*
|
||||
* Return 1 if 8390 was found, 0 if not.
|
||||
*/
|
||||
|
||||
int
|
||||
ed_probe_generic8390(sc)
|
||||
struct ed_softc *sc;
|
||||
{
|
||||
|
||||
if ((inb(sc->nic_addr + ED_P0_CR) &
|
||||
(ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
|
||||
(ED_CR_RD2 | ED_CR_STP))
|
||||
|
@ -230,15 +225,16 @@ ed_probe_generic8390(sc)
|
|||
* Probe and vendor-specific initialization routine for SMC/WD80x3 boards.
|
||||
*/
|
||||
int
|
||||
ed_probe_WD80x3(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
ed_probe_WD80x3(sc, cf, ia)
|
||||
struct ed_softc *sc;
|
||||
struct cfdata *cf;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
|
||||
int i;
|
||||
u_int memsize;
|
||||
u_char iptr, isa16bit, sum;
|
||||
|
||||
sc->asic_addr = isa_dev->id_iobase;
|
||||
sc->asic_addr = ia->ia_iobase;
|
||||
sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET;
|
||||
sc->is790 = 0;
|
||||
|
||||
|
@ -375,20 +371,20 @@ ed_probe_WD80x3(isa_dev)
|
|||
#ifdef ED_DEBUG
|
||||
printf("type=%x type_str=%s isa16bit=%d memsize=%d id_msize=%d\n",
|
||||
sc->type, sc->type_str ?: "unknown", isa16bit, memsize,
|
||||
isa_dev->id_msize);
|
||||
ia->ia_msize);
|
||||
for (i = 0; i < 8; i++)
|
||||
printf("%x -> %x\n", i, inb(sc->asic_addr + i));
|
||||
#endif
|
||||
/* Allow the user to override the autoconfiguration. */
|
||||
if (isa_dev->id_msize)
|
||||
memsize = isa_dev->id_msize;
|
||||
if (ia->ia_msize)
|
||||
memsize = ia->ia_msize;
|
||||
/*
|
||||
* (Note that if the user specifies both of the following flags that
|
||||
* '8-bit' mode intentionally has precedence.)
|
||||
*/
|
||||
if (isa_dev->id_flags & ED_FLAGS_FORCE_16BIT_MODE)
|
||||
if (cf->cf_flags & ED_FLAGS_FORCE_16BIT_MODE)
|
||||
isa16bit = 1;
|
||||
if (isa_dev->id_flags & ED_FLAGS_FORCE_8BIT_MODE)
|
||||
if (cf->cf_flags & ED_FLAGS_FORCE_8BIT_MODE)
|
||||
isa16bit = 0;
|
||||
|
||||
/*
|
||||
|
@ -400,43 +396,40 @@ ed_probe_WD80x3(isa_dev)
|
|||
if (sc->is790) {
|
||||
sc->ed_cr_rd2 = 0;
|
||||
/* Assemble together the encoded interrupt number. */
|
||||
outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04)
|
||||
| 0x80);
|
||||
iptr = ((inb(isa_dev->id_iobase + 0x0d) & 0x0c) >> 2) |
|
||||
((inb(isa_dev->id_iobase + 0x0d) & 0x40) >> 4);
|
||||
outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04)
|
||||
& ~0x80);
|
||||
outb(ia->ia_iobase + 0x04, inb(ia->ia_iobase + 0x04) | 0x80);
|
||||
iptr = ((inb(ia->ia_iobase + 0x0d) & 0x0c) >> 2) |
|
||||
((inb(ia->ia_iobase + 0x0d) & 0x40) >> 4);
|
||||
outb(ia->ia_iobase + 0x04, inb(ia->ia_iobase + 0x04) & ~0x80);
|
||||
/*
|
||||
* Translate it using translation table, and check for
|
||||
* correctness.
|
||||
*/
|
||||
if (ed_790_intr_mask[iptr] != isa_dev->id_irq) {
|
||||
if (ed_790_intr_mask[iptr] != ia->ia_irq) {
|
||||
printf("%s: kernel configured irq %d doesn't match board configured irq %d\n",
|
||||
sc->sc_dev.dv_xname, ffs(isa_dev->id_irq) - 1,
|
||||
sc->sc_dev.dv_xname, ffs(ia->ia_irq) - 1,
|
||||
ffs(ed_790_intr_mask[iptr]) - 1);
|
||||
return 0;
|
||||
}
|
||||
/* Enable the interrupt. */
|
||||
outb(isa_dev->id_iobase + 0x06, inb(isa_dev->id_iobase + 0x06)
|
||||
| 0x01);
|
||||
outb(ia->ia_iobase + 0x06, inb(ia->ia_iobase + 0x06) | 0x01);
|
||||
} else if (sc->type & ED_WD_SOFTCONFIG) {
|
||||
/* Assemble together the encoded interrupt number. */
|
||||
iptr = (inb(isa_dev->id_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
|
||||
((inb(isa_dev->id_iobase + ED_WD_IRR) &
|
||||
iptr = (inb(ia->ia_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
|
||||
((inb(ia->ia_iobase + ED_WD_IRR) &
|
||||
(ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5);
|
||||
/*
|
||||
* Translate it using translation table, and check for
|
||||
* correctness.
|
||||
*/
|
||||
if (ed_intr_mask[iptr] != isa_dev->id_irq) {
|
||||
if (ed_intr_mask[iptr] != ia->ia_irq) {
|
||||
printf("%s: kernel configured irq %d doesn't match board configured irq %d\n",
|
||||
sc->sc_dev.dv_xname, ffs(isa_dev->id_irq) - 1,
|
||||
sc->sc_dev.dv_xname, ffs(ia->ia_irq) - 1,
|
||||
ffs(ed_intr_mask[iptr]) - 1);
|
||||
return 0;
|
||||
}
|
||||
/* Enable the interrupt. */
|
||||
outb(isa_dev->id_iobase + ED_WD_IRR,
|
||||
inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
|
||||
outb(ia->ia_iobase + ED_WD_IRR,
|
||||
inb(ia->ia_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
|
||||
}
|
||||
|
||||
sc->isa16bit = isa16bit;
|
||||
|
@ -447,21 +440,22 @@ ed_probe_WD80x3(isa_dev)
|
|||
* mode - without mapping the NIC memory shared. ...Not the prefered
|
||||
* way, but it might be the only way.
|
||||
*/
|
||||
if (isa_dev->id_flags & ED_FLAGS_FORCE_PIO) {
|
||||
if (cf->cf_flags & ED_FLAGS_FORCE_PIO) {
|
||||
sc->mem_shared = 0;
|
||||
isa_dev->id_maddr = 0;
|
||||
} else
|
||||
ia->ia_msize = 0;
|
||||
} else {
|
||||
sc->mem_shared = 1;
|
||||
ia->ia_msize = memsize;
|
||||
}
|
||||
#else
|
||||
sc->mem_shared = 1;
|
||||
ia->ia_msize = memsize;
|
||||
#endif
|
||||
isa_dev->id_msize = memsize;
|
||||
|
||||
sc->mem_start = (caddr_t)isa_dev->id_maddr;
|
||||
sc->mem_start = (caddr_t)ia->ia_maddr;
|
||||
|
||||
/* Allocate one xmit buffer if < 16k, two buffers otherwise. */
|
||||
if ((memsize < 16384) ||
|
||||
(isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING))
|
||||
if ((memsize < 16384) || (cf->cf_flags & ED_FLAGS_NO_MULTI_BUFFERING))
|
||||
sc->txb_cnt = 1;
|
||||
else
|
||||
sc->txb_cnt = 2;
|
||||
|
@ -570,23 +564,25 @@ ed_probe_WD80x3(isa_dev)
|
|||
}
|
||||
}
|
||||
|
||||
return ED_WD_IO_PORTS;
|
||||
ia->ia_iosize = ED_WD_IO_PORTS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe and vendor-specific initialization routine for 3Com 3c503 boards.
|
||||
*/
|
||||
int
|
||||
ed_probe_3Com(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
ed_probe_3Com(sc, cf, ia)
|
||||
struct ed_softc *sc;
|
||||
struct cfdata *cf;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
|
||||
int i;
|
||||
u_int memsize;
|
||||
u_char isa16bit, sum;
|
||||
|
||||
sc->asic_addr = isa_dev->id_iobase + ED_3COM_ASIC_OFFSET;
|
||||
sc->nic_addr = isa_dev->id_iobase + ED_3COM_NIC_OFFSET;
|
||||
sc->asic_addr = ia->ia_iobase + ED_3COM_ASIC_OFFSET;
|
||||
sc->nic_addr = ia->ia_iobase + ED_3COM_NIC_OFFSET;
|
||||
sc->ed_cr_rd2 = ED_CR_RD2;
|
||||
|
||||
/*
|
||||
|
@ -599,35 +595,35 @@ ed_probe_3Com(isa_dev)
|
|||
*/
|
||||
switch (inb(sc->asic_addr + ED_3COM_BCFR)) {
|
||||
case ED_3COM_BCFR_300:
|
||||
if (isa_dev->id_iobase != 0x300)
|
||||
if (ia->ia_iobase != 0x300)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_310:
|
||||
if (isa_dev->id_iobase != 0x310)
|
||||
if (ia->ia_iobase != 0x310)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_330:
|
||||
if (isa_dev->id_iobase != 0x330)
|
||||
if (ia->ia_iobase != 0x330)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_350:
|
||||
if (isa_dev->id_iobase != 0x350)
|
||||
if (ia->ia_iobase != 0x350)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_250:
|
||||
if (isa_dev->id_iobase != 0x250)
|
||||
if (ia->ia_iobase != 0x250)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_280:
|
||||
if (isa_dev->id_iobase != 0x280)
|
||||
if (ia->ia_iobase != 0x280)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_2A0:
|
||||
if (isa_dev->id_iobase != 0x2a0)
|
||||
if (ia->ia_iobase != 0x2a0)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_BCFR_2E0:
|
||||
if (isa_dev->id_iobase != 0x2e0)
|
||||
if (ia->ia_iobase != 0x2e0)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
|
@ -640,26 +636,25 @@ ed_probe_3Com(isa_dev)
|
|||
*/
|
||||
switch (inb(sc->asic_addr + ED_3COM_PCFR)) {
|
||||
case ED_3COM_PCFR_DC000:
|
||||
if (kvtop(isa_dev->id_maddr) != 0xdc000)
|
||||
if (kvtop(ia->ia_maddr) != 0xdc000)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_PCFR_D8000:
|
||||
if (kvtop(isa_dev->id_maddr) != 0xd8000)
|
||||
if (kvtop(ia->ia_maddr) != 0xd8000)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_PCFR_CC000:
|
||||
if (kvtop(isa_dev->id_maddr) != 0xcc000)
|
||||
if (kvtop(ia->ia_maddr) != 0xcc000)
|
||||
return 0;
|
||||
break;
|
||||
case ED_3COM_PCFR_C8000:
|
||||
if (kvtop(isa_dev->id_maddr) != 0xc8000)
|
||||
if (kvtop(ia->ia_maddr) != 0xc8000)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset NIC and ASIC. Enable on-board transceiver throughout reset
|
||||
* sequence because it'll lock up if the cable isn't connected if we
|
||||
|
@ -731,7 +726,7 @@ ed_probe_3Com(isa_dev)
|
|||
/* Select page 0 registers. */
|
||||
outb(sc->nic_addr + ED_P2_CR, ED_CR_RD2 | ED_CR_STP);
|
||||
|
||||
sc->mem_start = (caddr_t)isa_dev->id_maddr;
|
||||
sc->mem_start = (caddr_t)ia->ia_maddr;
|
||||
sc->mem_size = memsize;
|
||||
sc->mem_end = sc->mem_start + memsize;
|
||||
|
||||
|
@ -745,7 +740,7 @@ ed_probe_3Com(isa_dev)
|
|||
* we optimize for linear transfers of same-size packets.)
|
||||
*/
|
||||
if (isa16bit) {
|
||||
if (isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING)
|
||||
if (cf->cf_flags & ED_FLAGS_NO_MULTI_BUFFERING)
|
||||
sc->txb_cnt = 1;
|
||||
else
|
||||
sc->txb_cnt = 2;
|
||||
|
@ -775,7 +770,7 @@ ed_probe_3Com(isa_dev)
|
|||
outb(sc->asic_addr + ED_3COM_PSPR, sc->rec_page_stop);
|
||||
|
||||
/* Set IRQ. 3c503 only allows a choice of irq 3-5 or 9. */
|
||||
switch (isa_dev->id_irq) {
|
||||
switch (ia->ia_irq) {
|
||||
case IRQ9:
|
||||
outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ2);
|
||||
break;
|
||||
|
@ -790,7 +785,7 @@ ed_probe_3Com(isa_dev)
|
|||
break;
|
||||
default:
|
||||
printf("%s: invalid irq configuration (%d) must be 3-5 or 9 for 3c503\n",
|
||||
sc->sc_dev.dv_xname, ffs(isa_dev->id_irq) - 1);
|
||||
sc->sc_dev.dv_xname, ffs(ia->ia_irq) - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -821,25 +816,27 @@ ed_probe_3Com(isa_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
isa_dev->id_msize = memsize;
|
||||
return ED_3COM_IO_PORTS;
|
||||
ia->ia_msize = memsize;
|
||||
ia->ia_iosize = ED_3COM_IO_PORTS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe and vendor-specific initialization routine for NE1000/2000 boards.
|
||||
*/
|
||||
int
|
||||
ed_probe_Novell(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
ed_probe_Novell(sc, cf, ia)
|
||||
struct ed_softc *sc;
|
||||
struct cfdata *cf;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
|
||||
u_int memsize, n;
|
||||
u_char romdata[16], isa16bit = 0, tmp;
|
||||
static u_char test_pattern[32] = "THIS is A memory TEST pattern";
|
||||
u_char test_buffer[32];
|
||||
|
||||
sc->asic_addr = isa_dev->id_iobase + ED_NOVELL_ASIC_OFFSET;
|
||||
sc->nic_addr = isa_dev->id_iobase + ED_NOVELL_NIC_OFFSET;
|
||||
sc->asic_addr = ia->ia_iobase + ED_NOVELL_ASIC_OFFSET;
|
||||
sc->nic_addr = ia->ia_iobase + ED_NOVELL_NIC_OFFSET;
|
||||
sc->ed_cr_rd2 = ED_CR_RD2;
|
||||
|
||||
/* XXX - do Novell-specific probe here */
|
||||
|
@ -884,7 +881,7 @@ ed_probe_Novell(isa_dev)
|
|||
|
||||
sc->vendor = ED_VENDOR_NOVELL;
|
||||
sc->mem_shared = 0;
|
||||
isa_dev->id_maddr = 0;
|
||||
ia->ia_msize = 0;
|
||||
|
||||
/*
|
||||
* Test the ability to read and write to the NIC memory. This has the
|
||||
|
@ -944,8 +941,8 @@ ed_probe_Novell(isa_dev)
|
|||
|
||||
#if 0 /* probably not useful - NE boards only come two ways */
|
||||
/* Allow kernel config file overrides. */
|
||||
if (isa_dev->id_msize)
|
||||
memsize = isa_dev->id_msize;
|
||||
if (ia->ia_msize)
|
||||
memsize = ia->ia_msize;
|
||||
#endif
|
||||
|
||||
sc->mem_size = memsize;
|
||||
|
@ -960,8 +957,7 @@ ed_probe_Novell(isa_dev)
|
|||
* Use one xmit buffer if < 16k, two buffers otherwise (if not told
|
||||
* otherwise).
|
||||
*/
|
||||
if ((memsize < 16384) ||
|
||||
(isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING))
|
||||
if ((memsize < 16384) || (cf->cf_flags & ED_FLAGS_NO_MULTI_BUFFERING))
|
||||
sc->txb_cnt = 1;
|
||||
else
|
||||
sc->txb_cnt = 2;
|
||||
|
@ -979,17 +975,20 @@ ed_probe_Novell(isa_dev)
|
|||
/* Clear any pending interrupts that might have occurred above. */
|
||||
outb(sc->nic_addr + ED_P0_ISR, 0xff);
|
||||
|
||||
return ED_NOVELL_IO_PORTS;
|
||||
ia->ia_iosize = ED_NOVELL_IO_PORTS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Install interface into kernel networking data structures.
|
||||
*/
|
||||
int
|
||||
ed_attach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
edattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
|
||||
struct ed_softc *sc = (void *)self;
|
||||
struct cfdata *cf = sc->sc_dev.dv_cfdata;
|
||||
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
|
@ -999,7 +998,7 @@ ed_attach(isa_dev)
|
|||
|
||||
/* Initialize ifnet structure. */
|
||||
ifp->if_unit = sc->sc_dev.dv_unit;
|
||||
ifp->if_name = eddriver.name;
|
||||
ifp->if_name = edcd.cd_name;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_output = ether_output;
|
||||
ifp->if_start = ed_start;
|
||||
|
@ -1012,7 +1011,7 @@ ed_attach(isa_dev)
|
|||
* Set default state for LINK0 flag (used to disable the tranceiver
|
||||
* for AUI operation), based on compile-time config option.
|
||||
*/
|
||||
if (isa_dev->id_flags & ED_FLAGS_DISABLE_TRANCEIVER)
|
||||
if (cf->cf_flags & ED_FLAGS_DISABLE_TRANCEIVER)
|
||||
ifp->if_flags |= IFF_LINK0;
|
||||
|
||||
/* Attach the interface. */
|
||||
|
@ -1040,8 +1039,7 @@ ed_attach(isa_dev)
|
|||
}
|
||||
|
||||
/* Print additional info when attached. */
|
||||
printf("%s: address %s, ", sc->sc_dev.dv_xname,
|
||||
ether_sprintf(sc->sc_arpcom.ac_enaddr));
|
||||
printf(": address %s, ", ether_sprintf(sc->sc_arpcom.ac_enaddr));
|
||||
|
||||
if (sc->type_str && (*sc->type_str != '\0'))
|
||||
printf("type %s ", sc->type_str);
|
||||
|
@ -1056,7 +1054,6 @@ ed_attach(isa_dev)
|
|||
#if NBPFILTER > 0
|
||||
bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1102,7 +1099,7 @@ int
|
|||
ed_watchdog(unit)
|
||||
short unit;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[unit];
|
||||
struct ed_softc *sc = edcd.cd_devs[unit];
|
||||
|
||||
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
|
||||
++sc->sc_arpcom.ac_if.if_oerrors;
|
||||
|
@ -1306,7 +1303,7 @@ int
|
|||
ed_start(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[ifp->if_unit];
|
||||
struct ed_softc *sc = edcd.cd_devs[ifp->if_unit];
|
||||
struct mbuf *m0, *m;
|
||||
caddr_t buffer;
|
||||
int len;
|
||||
|
@ -1565,7 +1562,7 @@ int
|
|||
edintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[unit];
|
||||
struct ed_softc *sc = edcd.cd_devs[unit];
|
||||
u_char isr;
|
||||
|
||||
/* Set NIC to page 0 registers. */
|
||||
|
@ -1750,7 +1747,7 @@ ed_ioctl(ifp, command, data)
|
|||
int command;
|
||||
caddr_t data;
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[ifp->if_unit];
|
||||
struct ed_softc *sc = edcd.cd_devs[ifp->if_unit];
|
||||
register struct ifaddr *ifa = (struct ifaddr *)data;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
int s, error = 0;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
/*
|
||||
* 3COM Etherlink 3C501 device driver
|
||||
*
|
||||
* $Id: if_el.c,v 1.7 1994/03/08 12:21:21 mycroft Exp $
|
||||
* $Id: if_el.c,v 1.8 1994/03/29 04:35:51 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -18,7 +18,6 @@
|
|||
* - Does not currently support multicasts
|
||||
*/
|
||||
|
||||
#include "el.h"
|
||||
#include "bpfilter.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -55,7 +54,7 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/if_elreg.h>
|
||||
|
||||
|
@ -80,16 +79,14 @@ struct el_softc {
|
|||
u_short sc_iobase; /* base I/O addr */
|
||||
caddr_t sc_bpf; /* BPF magic cookie */
|
||||
char sc_pktbuf[EL_BUFSIZ]; /* frame buffer */
|
||||
} el_softc[NEL];
|
||||
};
|
||||
|
||||
/*
|
||||
* prototypes
|
||||
*/
|
||||
int elintr __P((int));
|
||||
static int el_attach __P((struct isa_device *));
|
||||
static int el_init __P((struct el_softc *));
|
||||
static int el_ioctl __P((struct ifnet *, int, caddr_t));
|
||||
static int el_probe __P((struct isa_device *));
|
||||
static int el_start __P((struct ifnet *));
|
||||
static int el_watchdog __P((int));
|
||||
static void el_reset __P((struct el_softc *));
|
||||
|
@ -99,9 +96,12 @@ static inline void elread __P((struct el_softc *, caddr_t, int));
|
|||
static struct mbuf *elget __P((caddr_t, int, int, struct ifnet *));
|
||||
static inline void el_hardreset __P((struct el_softc *));
|
||||
|
||||
int elprobe();
|
||||
void elattach();
|
||||
|
||||
/* isa_driver structure for autoconf */
|
||||
struct isa_driver eldriver = {
|
||||
el_probe, el_attach, "el"
|
||||
struct cfdriver elcd = {
|
||||
NULL, "el", elprobe, elattach, DV_IFNET, sizeof(struct el_softc)
|
||||
};
|
||||
|
||||
struct trailer_header {
|
||||
|
@ -115,12 +115,14 @@ struct trailer_header {
|
|||
* See if the card is there and at the right place.
|
||||
* (XXX - cgd -- needs help)
|
||||
*/
|
||||
static int
|
||||
el_probe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
int
|
||||
elprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct el_softc *sc = &el_softc[isa_dev->id_unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct el_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_char station_addr[ETHER_ADDR_LEN];
|
||||
int i;
|
||||
|
||||
|
@ -131,10 +133,6 @@ el_probe(isa_dev)
|
|||
/* Grab some info for our structure. */
|
||||
sc->sc_iobase = iobase;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", eldriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
/*
|
||||
* Now attempt to grab the station address from the PROM and see if it
|
||||
* contains the 3com vendor code.
|
||||
|
@ -168,7 +166,10 @@ el_probe(isa_dev)
|
|||
dprintf(("Vendor code ok.\n"));
|
||||
/* Copy the station address into the arpcom structure. */
|
||||
bcopy(station_addr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
|
||||
return 1; /* XXX - cgd? */
|
||||
|
||||
ia->ia_iosize = 4; /* XXX */
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -176,11 +177,12 @@ el_probe(isa_dev)
|
|||
* called, we know that the card exists at the given I/O address. We still
|
||||
* assume that the IRQ given is correct.
|
||||
*/
|
||||
static int
|
||||
el_attach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
elattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct el_softc *sc = &el_softc[isa_dev->id_unit];
|
||||
struct el_softc *sc = (void *)self;
|
||||
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
|
@ -191,8 +193,8 @@ el_attach(isa_dev)
|
|||
el_stop(sc);
|
||||
|
||||
/* Initialize ifnet structure. */
|
||||
ifp->if_unit = isa_dev->id_unit;
|
||||
ifp->if_name = eldriver.name;
|
||||
ifp->if_unit = sc->sc_dev.dv_unit;
|
||||
ifp->if_name = elcd.cd_name;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_output = ether_output;
|
||||
ifp->if_start = el_start;
|
||||
|
@ -235,8 +237,7 @@ el_attach(isa_dev)
|
|||
bpfattach(&sc->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
|
||||
#endif
|
||||
|
||||
dprintf(("el_attach() finished.\n"));
|
||||
return 1;
|
||||
dprintf(("elattach() finished.\n"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -340,7 +341,7 @@ static int
|
|||
el_start(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct el_softc *sc = &el_softc[ifp->if_unit];
|
||||
struct el_softc *sc = elcd.cd_devs[ifp->if_unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
struct mbuf *m, *m0;
|
||||
int s, i, len, retries, done;
|
||||
|
@ -479,7 +480,7 @@ int
|
|||
elintr(unit)
|
||||
int unit;
|
||||
{
|
||||
register struct el_softc *sc = &el_softc[unit];
|
||||
register struct el_softc *sc = elcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
int stat, rxstat, len, done;
|
||||
|
||||
|
@ -732,7 +733,7 @@ el_ioctl(ifp, command, data)
|
|||
int command;
|
||||
caddr_t data;
|
||||
{
|
||||
struct el_softc *sc = &el_softc[ifp->if_unit];
|
||||
struct el_softc *sc = elcd.cd_devs[ifp->if_unit];
|
||||
register struct ifaddr *ifa = (struct ifaddr *)data;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
int s, error = 0;
|
||||
|
@ -826,7 +827,7 @@ static int
|
|||
el_watchdog(unit)
|
||||
int unit;
|
||||
{
|
||||
struct el_softc *sc = &el_softc[unit];
|
||||
struct el_softc *sc = elcd.cd_devs[unit];
|
||||
|
||||
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
|
||||
sc->sc_arpcom.ac_if.if_oerrors++;
|
||||
|
|
|
@ -21,17 +21,14 @@
|
|||
* (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: if_ep.c,v 1.24 1994/03/14 06:57:25 hpeyerl Exp $
|
||||
* $Id: if_ep.c,v 1.25 1994/03/29 04:35:53 mycroft Exp $
|
||||
*/
|
||||
/*
|
||||
* TODO:
|
||||
* Multi-509 configs.
|
||||
* don't pass unit into epstop.
|
||||
* epintr returns an int for magnum. 0=not for me. 1=for me. -1=whoknows?
|
||||
* deallocate mbufs when ifconfig'd down.
|
||||
*/
|
||||
|
||||
#include "ep.h"
|
||||
#include "bpfilter.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -41,6 +38,7 @@
|
|||
#include <sys/errno.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/netisr.h>
|
||||
|
@ -69,9 +67,7 @@
|
|||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/if_epreg.h>
|
||||
#include <i386/isa/elink.h>
|
||||
|
||||
|
@ -82,8 +78,11 @@
|
|||
* Ethernet software status per interface.
|
||||
*/
|
||||
struct ep_softc {
|
||||
struct device sc_dev;
|
||||
struct intrhand sc_ih;
|
||||
|
||||
struct arpcom ep_ac; /* Ethernet common part */
|
||||
short ep_io_addr; /* i/o bus address */
|
||||
short ep_iobase; /* i/o bus address */
|
||||
char ep_connectors; /* Connectors on this card. */
|
||||
#define MAX_MBS 4 /* # of mbufs we keep around */
|
||||
struct mbuf *mb[MAX_MBS]; /* spare mbuf storage. */
|
||||
|
@ -91,29 +90,27 @@ struct ep_softc {
|
|||
int last_mb; /* Last mbuf. */
|
||||
int tx_start_thresh; /* Current TX_start_thresh. */
|
||||
caddr_t bpf; /* BPF "magic cookie" */
|
||||
} ep_softc[NEP];
|
||||
};
|
||||
|
||||
static int epprobe __P((struct isa_device *));
|
||||
static int epattach __P((struct isa_device *));
|
||||
static int epprobe();
|
||||
static void epattach();
|
||||
|
||||
struct isa_driver epdriver = {
|
||||
epprobe,
|
||||
epattach,
|
||||
"ep"
|
||||
struct cfdriver epcd = {
|
||||
NULL, "ep", epprobe, epattach, DV_IFNET, sizeof(struct ep_softc)
|
||||
};
|
||||
|
||||
int epintr __P((int));
|
||||
static int epinit __P((int));
|
||||
static int epioctl __P((struct ifnet * ifp, int, caddr_t));
|
||||
static void epinit __P((struct ep_softc *));
|
||||
static int epioctl __P((struct ifnet *, int, caddr_t));
|
||||
static int epstart __P((struct ifnet *));
|
||||
static int epwatchdog __P((int));
|
||||
static void epreset __P((int));
|
||||
static void epreset __P((struct ep_softc *));
|
||||
static void epread __P((struct ep_softc *));
|
||||
static void epmbufqueue __P((struct ep_softc *));
|
||||
static void epstop __P((int));
|
||||
static void epstop __P((struct ep_softc *));
|
||||
|
||||
static u_short epreadeeprom __P((int id_port, int offset));
|
||||
static int epbusyeeprom __P((struct isa_device * is));
|
||||
static int epbusyeeprom __P((struct ep_softc *));
|
||||
|
||||
/*
|
||||
* Eisa probe routine. If any part of this probe should fail to
|
||||
|
@ -122,10 +119,12 @@ static int epbusyeeprom __P((struct isa_device * is));
|
|||
* at the moment.
|
||||
*/
|
||||
int
|
||||
epprobe(is)
|
||||
struct isa_device *is;
|
||||
epprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ep_softc *sc = &ep_softc[is->id_unit];
|
||||
struct ep_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
int port;
|
||||
int i;
|
||||
int eisa_slot;
|
||||
|
@ -142,18 +141,20 @@ epprobe(is)
|
|||
}
|
||||
k = inw(port + EP_W0_PRODUCT_ID);
|
||||
if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
|
||||
return(isa_epprobe(is));
|
||||
return isa_epprobe(sc, ia);
|
||||
|
||||
k = inw(port + EP_W0_ADDRESS_CFG);
|
||||
k = (k & 0x1f) * 0x10 + 0x200; /* decode base addr. */
|
||||
|
||||
k = inw(port + EP_W0_RESOURCE_CFG);
|
||||
k >>= 12;
|
||||
if (is->id_irq != (1 << ((k == 2) ? 9 : k)))
|
||||
return (isa_epprobe(is));
|
||||
if (ia->ia_irq != (1 << ((k == 2) ? 9 : k)))
|
||||
return isa_epprobe(sc, ia);
|
||||
|
||||
is->id_iobase = port; /* Set the base addr for later */
|
||||
return(0x10);
|
||||
ia->ia_iobase = port; /* Set the base addr for later */
|
||||
ia->ia_iosize = 0x10;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -164,10 +165,10 @@ epprobe(is)
|
|||
* Magnum config holds promise of a fix but we'll have to wait a bit.
|
||||
*/
|
||||
int
|
||||
isa_epprobe(is)
|
||||
struct isa_device *is;
|
||||
isa_epprobe(sc, ia)
|
||||
struct ep_softc *sc;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
struct ep_softc *sc = &ep_softc[is->id_unit];
|
||||
u_short k;
|
||||
|
||||
outw(BASE + EP_COMMAND, GLOBAL_RESET);
|
||||
|
@ -191,12 +192,12 @@ isa_epprobe(is)
|
|||
|
||||
k = epreadeeprom(ELINK_ID_PORT, EEPROM_ADDR_CFG); /* get addr cfg */
|
||||
k = (k & 0x1f) * 0x10 + 0x200; /* decode base addr. */
|
||||
if (k != is->id_iobase)
|
||||
if (k != ia->ia_iobase)
|
||||
return (0);
|
||||
|
||||
k = epreadeeprom(ELINK_ID_PORT, EEPROM_RESOURCE_CFG);
|
||||
k >>= 12;
|
||||
if (is->id_irq != (1 << ((k == 2) ? 9 : k)))
|
||||
if (ia->ia_irq != (1 << ((k == 2) ? 9 : k)))
|
||||
return (0);
|
||||
|
||||
outb(ELINK_ID_PORT, ACTIVATE_ADAPTER_TO_CONFIG);
|
||||
|
@ -204,22 +205,24 @@ isa_epprobe(is)
|
|||
return (0x10); /* 16 bytes of I/O space used. */
|
||||
}
|
||||
|
||||
static int
|
||||
epattach(is)
|
||||
struct isa_device *is;
|
||||
static void
|
||||
epattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ep_softc *sc = &ep_softc[is->id_unit];
|
||||
struct ep_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct ifnet *ifp = &sc->ep_ac.ac_if;
|
||||
u_short i;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
u_short i;
|
||||
|
||||
sc->ep_io_addr = is->id_iobase;
|
||||
printf(": ");
|
||||
|
||||
printf("ep%d: ", is->id_unit);
|
||||
sc->ep_iobase = ia->ia_iobase;
|
||||
|
||||
sc->ep_connectors = 0;
|
||||
i = inw(is->id_iobase + EP_W0_CONFIG_CTRL);
|
||||
i = inw(ia->ia_iobase + EP_W0_CONFIG_CTRL);
|
||||
if (i & IS_AUI) {
|
||||
printf("aui");
|
||||
sc->ep_connectors |= AUI;
|
||||
|
@ -245,11 +248,11 @@ epattach(is)
|
|||
for (i = 0; i < 3; i++) {
|
||||
u_short *p;
|
||||
GO_WINDOW(0);
|
||||
if (epbusyeeprom(is))
|
||||
return (0);
|
||||
if (epbusyeeprom(sc))
|
||||
return;
|
||||
outw(BASE + EP_W0_EEPROM_COMMAND, READ_EEPROM | i);
|
||||
if (epbusyeeprom(is))
|
||||
return (0);
|
||||
if (epbusyeeprom(sc))
|
||||
return;
|
||||
p = (u_short *) & sc->ep_ac.ac_enaddr[i * 2];
|
||||
*p = htons(inw(BASE + EP_W0_EEPROM_DATA));
|
||||
GO_WINDOW(2);
|
||||
|
@ -257,8 +260,8 @@ epattach(is)
|
|||
}
|
||||
printf(" address %s\n", ether_sprintf(sc->ep_ac.ac_enaddr));
|
||||
|
||||
ifp->if_unit = is->id_unit;
|
||||
ifp->if_name = "ep";
|
||||
ifp->if_unit = sc->sc_dev.dv_unit;
|
||||
ifp->if_name = epcd.cd_name;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
|
||||
ifp->if_output = ether_output;
|
||||
|
@ -269,43 +272,43 @@ epattach(is)
|
|||
if_attach(ifp);
|
||||
|
||||
/*
|
||||
* Fill the hardware address into ifa_addr if we find an
|
||||
* AF_LINK entry. We need to do this so bpf's can get the hardware
|
||||
* addr of this card. netstat likes this too!
|
||||
* Search down the ifa address list looking for the AF_LINK type entry
|
||||
* and initialize it.
|
||||
*/
|
||||
ifa = ifp->if_addrlist;
|
||||
while ((ifa != 0) && (ifa->ifa_addr != 0) &&
|
||||
(ifa->ifa_addr->sa_family != AF_LINK))
|
||||
ifa = ifa->ifa_next;
|
||||
|
||||
if ((ifa != 0) && (ifa->ifa_addr != 0)) {
|
||||
sdl = (struct sockaddr_dl *) ifa->ifa_addr;
|
||||
sdl->sdl_type = IFT_ETHER;
|
||||
sdl->sdl_alen = ETHER_ADDR_LEN;
|
||||
sdl->sdl_slen = 0;
|
||||
bcopy(sc->ep_ac.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN);
|
||||
while (ifa && ifa->ifa_addr) {
|
||||
if (ifa->ifa_addr->sa_family == AF_LINK) {
|
||||
/*
|
||||
* Fill in the link-level address for this interface.
|
||||
*/
|
||||
sdl = (struct sockaddr_dl *) ifa->ifa_addr;
|
||||
sdl->sdl_type = IFT_ETHER;
|
||||
sdl->sdl_alen = ETHER_ADDR_LEN;
|
||||
sdl->sdl_slen = 0;
|
||||
bcopy(sc->ep_ac.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN);
|
||||
break;
|
||||
} else
|
||||
ifa = ifa->ifa_next;
|
||||
}
|
||||
|
||||
#if NBPFILTER > 0
|
||||
bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The order in here seems important. Otherwise we may not receive
|
||||
* interrupts. ?!
|
||||
*/
|
||||
static int
|
||||
epinit(unit)
|
||||
int unit;
|
||||
static void
|
||||
epinit(sc)
|
||||
register struct ep_softc *sc;
|
||||
{
|
||||
register struct ep_softc *sc = &ep_softc[unit];
|
||||
register struct ifnet *ifp = &sc->ep_ac.ac_if;
|
||||
int s, i;
|
||||
|
||||
if (ifp->if_addrlist == (struct ifaddr *) 0)
|
||||
return (0);
|
||||
if (ifp->if_addrlist == 0)
|
||||
return;
|
||||
|
||||
s = splimp();
|
||||
while (inb(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
|
||||
|
@ -379,7 +382,6 @@ epinit(unit)
|
|||
|
||||
epstart(ifp);
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const char padmap[] = {0, 3, 2, 1};
|
||||
|
@ -388,7 +390,7 @@ static int
|
|||
epstart(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
register struct ep_softc *sc = &ep_softc[ifp->if_unit];
|
||||
register struct ep_softc *sc = epcd.cd_devs[ifp->if_unit];
|
||||
struct mbuf *m, *top;
|
||||
int s, len, pad;
|
||||
|
||||
|
@ -540,18 +542,18 @@ epintr(unit)
|
|||
int unit;
|
||||
{
|
||||
int status, i;
|
||||
register struct ep_softc *sc = &ep_softc[unit];
|
||||
register struct ep_softc *sc = epcd.cd_devs[unit];
|
||||
struct ifnet *ifp = &sc->ep_ac.ac_if;
|
||||
|
||||
status = 0;
|
||||
checkintr:
|
||||
status = inw(BASE + EP_STATUS) &
|
||||
(S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE | S_CARD_FAILURE);
|
||||
if (status == 0) {
|
||||
/* No interrupts. */
|
||||
outw(BASE + EP_COMMAND, C_INTR_LATCH);
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
loop:
|
||||
/* important that we do this first. */
|
||||
outw(BASE + EP_COMMAND, ACK_INTR | status);
|
||||
|
||||
|
@ -566,9 +568,9 @@ checkintr:
|
|||
epread(sc);
|
||||
}
|
||||
if (status & S_CARD_FAILURE) {
|
||||
printf("ep%d: reset (status: %x)\n", unit, status);
|
||||
printf("%s: reset (status: %x)\n", sc->sc_dev.dv_xname, status);
|
||||
outw(BASE + EP_COMMAND, C_INTR_LATCH);
|
||||
epinit(unit);
|
||||
epinit(sc);
|
||||
return (1);
|
||||
}
|
||||
if (status & S_TX_COMPLETE) {
|
||||
|
@ -599,7 +601,14 @@ checkintr:
|
|||
}
|
||||
epstart(ifp);
|
||||
}
|
||||
goto checkintr;
|
||||
status = inw(BASE + EP_STATUS) &
|
||||
(S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE | S_CARD_FAILURE);
|
||||
if (status == 0) {
|
||||
/* No interrupts. */
|
||||
outw(BASE + EP_COMMAND, C_INTR_LATCH);
|
||||
return (1);
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -764,7 +773,7 @@ epioctl(ifp, cmd, data)
|
|||
caddr_t data;
|
||||
{
|
||||
register struct ifaddr *ifa = (struct ifaddr *) data;
|
||||
struct ep_softc *sc = &ep_softc[ifp->if_unit];
|
||||
struct ep_softc *sc = epcd.cd_devs[ifp->if_unit];
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0;
|
||||
|
||||
|
@ -774,7 +783,7 @@ epioctl(ifp, cmd, data)
|
|||
switch (ifa->ifa_addr->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
epinit(ifp->if_unit); /* before arpwhohas */
|
||||
epinit(sc); /* before arpwhohas */
|
||||
((struct arpcom *) ifp)->ac_ipaddr = IA_SIN(ifa)->sin_addr;
|
||||
arpwhohas((struct arpcom *) ifp, &IA_SIN(ifa)->sin_addr);
|
||||
break;
|
||||
|
@ -793,23 +802,23 @@ epioctl(ifp, cmd, data)
|
|||
sc->ep_ac.ac_enaddr,
|
||||
sizeof(sc->ep_ac.ac_enaddr));
|
||||
}
|
||||
epinit(ifp->if_unit);
|
||||
epinit(sc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
epinit(ifp->if_unit);
|
||||
epinit(sc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SIOCSIFFLAGS:
|
||||
if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
|
||||
ifp->if_flags &= ~IFF_RUNNING;
|
||||
epstop(ifp->if_unit);
|
||||
epstop(sc);
|
||||
break;
|
||||
}
|
||||
if (ifp->if_flags & IFF_UP && (ifp->if_flags & IFF_RUNNING) == 0)
|
||||
epinit(ifp->if_unit);
|
||||
epinit(sc);
|
||||
break;
|
||||
#ifdef notdef
|
||||
case SIOCGHWADDR:
|
||||
|
@ -824,13 +833,13 @@ epioctl(ifp, cmd, data)
|
|||
}
|
||||
|
||||
static void
|
||||
epreset(unit)
|
||||
int unit;
|
||||
epreset(sc)
|
||||
struct ep_softc *sc;
|
||||
{
|
||||
int s = splimp();
|
||||
|
||||
epstop(unit);
|
||||
epinit(unit);
|
||||
epstop(sc);
|
||||
epinit(sc);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
@ -838,16 +847,17 @@ static int
|
|||
epwatchdog(unit)
|
||||
int unit;
|
||||
{
|
||||
log(LOG_ERR, "ep%d: watchdog\n", unit);
|
||||
epreset(unit);
|
||||
register struct ep_softc *sc = epcd.cd_devs[unit];
|
||||
|
||||
log(LOG_ERR, "%s: watchdog\n", sc->sc_dev.dv_xname);
|
||||
epreset(sc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
epstop(unit)
|
||||
int unit;
|
||||
epstop(sc)
|
||||
register struct ep_softc *sc;
|
||||
{
|
||||
register struct ep_softc *sc = &ep_softc[unit];
|
||||
|
||||
outw(BASE + EP_COMMAND, RX_DISABLE);
|
||||
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
|
||||
|
@ -883,6 +893,7 @@ epreadeeprom(id_port, offset)
|
|||
int offset;
|
||||
{
|
||||
int i, data = 0;
|
||||
|
||||
outb(id_port, 0x80 + offset);
|
||||
delay(1000);
|
||||
for (i = 0; i < 16; i++)
|
||||
|
@ -891,25 +902,26 @@ epreadeeprom(id_port, offset)
|
|||
}
|
||||
|
||||
static int
|
||||
epbusyeeprom(is)
|
||||
struct isa_device *is;
|
||||
epbusyeeprom(sc)
|
||||
struct ep_softc *sc;
|
||||
{
|
||||
int i = 0, j;
|
||||
register struct ep_softc *sc = &ep_softc[is->id_unit];
|
||||
int i = 100, j;
|
||||
|
||||
while (i++ < 100) {
|
||||
while (i--) {
|
||||
j = inw(BASE + EP_W0_EEPROM_COMMAND);
|
||||
if (j & EEPROM_BUSY)
|
||||
delay(100);
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (i >= 100) {
|
||||
printf("\nep%d: eeprom failed to come ready.\n", is->id_unit);
|
||||
if (!i) {
|
||||
printf("\n%s: eeprom failed to come ready.\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
return (1);
|
||||
}
|
||||
if (j & EEPROM_TST_MODE) {
|
||||
printf("\nep%d: 3c509 in test mode. Erase pencil mark!\n", is->id_unit);
|
||||
printf("\n%s: 3c509 in test mode. Erase pencil mark!\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* (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: if_epreg.h,v 1.2 1994/01/28 23:44:41 jtc Exp $
|
||||
* $Id: if_epreg.h,v 1.3 1994/03/29 04:35:56 mycroft Exp $
|
||||
*/
|
||||
/**************************************************************************
|
||||
* *
|
||||
|
@ -277,7 +277,7 @@
|
|||
#define ENABLE_DRQ_IRQ 0x0001
|
||||
#define MFG_ID 0x6d50
|
||||
#define PROD_ID 0x9150
|
||||
#define BASE sc->ep_io_addr
|
||||
#define BASE sc->ep_iobase
|
||||
#define GO_WINDOW(x) outw(BASE+EP_COMMAND, WINDOW_SELECT|x)
|
||||
#define AUI 0x1
|
||||
#define BNC 0x2
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_ie.c,v 1.6 1994/03/06 17:19:04 mycroft Exp $
|
||||
* $Id: if_ie.c,v 1.7 1994/03/29 04:35:58 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -100,7 +100,6 @@ interval [sc_maddr, sc_maddr + sc_msize); to make 24-pointers, we subtract
|
|||
iomem, and to make 16-pointers, we subtract sc_maddr and and with 0xffff.
|
||||
*/
|
||||
|
||||
#include "ie.h"
|
||||
#include "bpfilter.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -143,9 +142,7 @@ iomem, and to make 16-pointers, we subtract sc_maddr and and with 0xffff.
|
|||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/ic/i82586.h>
|
||||
#include <i386/isa/if_ieatt.h>
|
||||
#include <i386/isa/if_ie507.h>
|
||||
|
@ -251,10 +248,8 @@ struct ie_softc {
|
|||
#if NBPFILTER > 0
|
||||
caddr_t sc_bpf;
|
||||
#endif
|
||||
} ie_softc[NIE];
|
||||
};
|
||||
|
||||
int ieprobe __P((struct isa_device *));
|
||||
int ieattach __P((struct isa_device *));
|
||||
int iewatchdog __P((/* short */));
|
||||
int ieintr __P((int));
|
||||
int ieinit __P((struct ie_softc *sc));
|
||||
|
@ -286,10 +281,11 @@ int in_ierint = 0;
|
|||
int in_ietint = 0;
|
||||
#endif
|
||||
|
||||
struct isa_driver iedriver = {
|
||||
ieprobe,
|
||||
ieattach,
|
||||
"ie"
|
||||
int ieprobe();
|
||||
void ieattach();
|
||||
|
||||
struct cfdriver iecd = {
|
||||
NULL, "ie", ieprobe, ieattach, DV_IFNET, sizeof(struct ie_softc)
|
||||
};
|
||||
|
||||
#define MK_24(base, ptr) ((caddr_t)((u_long)ptr - (u_long)base))
|
||||
|
@ -350,32 +346,29 @@ ie_ack(sc, mask)
|
|||
}
|
||||
|
||||
int
|
||||
ieprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
ieprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[isa_dev->id_unit];
|
||||
int nports;
|
||||
struct ie_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", iedriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
if (nports = sl_probe(isa_dev, sc))
|
||||
return nports;
|
||||
if (nports = el_probe(isa_dev, sc))
|
||||
return nports;
|
||||
if (sl_probe(sc, ia))
|
||||
return 1;
|
||||
if (el_probe(sc, ia))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sl_probe(isa_dev, sc)
|
||||
struct isa_device *isa_dev;
|
||||
sl_probe(sc, ia)
|
||||
struct ie_softc *sc;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
u_char c;
|
||||
|
||||
sc->sc_iobase = isa_dev->id_iobase;
|
||||
sc->sc_maddr = isa_dev->id_maddr;
|
||||
sc->sc_iobase = ia->ia_iobase;
|
||||
sc->sc_maddr = ia->ia_maddr;
|
||||
|
||||
c = inb(PORT + IEATT_REVISION);
|
||||
switch(SL_BOARD(c)) {
|
||||
|
@ -408,11 +401,11 @@ sl_probe(isa_dev, sc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!isa_dev->id_msize)
|
||||
isa_dev->id_msize = sc->sc_msize;
|
||||
else if (isa_dev->id_msize != sc->sc_msize) {
|
||||
if (!ia->ia_msize)
|
||||
ia->ia_msize = sc->sc_msize;
|
||||
else if (ia->ia_msize != sc->sc_msize) {
|
||||
printf("%s: kernel configured msize %d doesn't match board configured msize %d\n",
|
||||
sc->sc_dev.dv_xname, isa_dev->id_msize, sc->sc_msize);
|
||||
sc->sc_dev.dv_xname, ia->ia_msize, sc->sc_msize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -420,20 +413,21 @@ sl_probe(isa_dev, sc)
|
|||
sc->chan_attn = sl_chan_attn;
|
||||
slel_get_address(sc);
|
||||
|
||||
return 16;
|
||||
ia->ia_iosize = 16;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
el_probe(isa_dev, sc)
|
||||
struct isa_device *isa_dev;
|
||||
el_probe(sc, ia)
|
||||
struct ie_softc *sc;
|
||||
struct isa_attach_args *ia;
|
||||
{
|
||||
u_char c;
|
||||
int i;
|
||||
u_char signature[] = "*3COM*";
|
||||
|
||||
sc->sc_iobase = isa_dev->id_iobase;
|
||||
sc->sc_maddr = isa_dev->id_maddr;
|
||||
sc->sc_iobase = ia->ia_iobase;
|
||||
sc->sc_maddr = ia->ia_maddr;
|
||||
|
||||
/* Reset and put card in CONFIG state without changing address. */
|
||||
elink_reset();
|
||||
|
@ -462,17 +456,17 @@ el_probe(isa_dev, sc)
|
|||
|
||||
c = inb(PORT + IE507_IRQ) & 0x0f;
|
||||
|
||||
if (isa_dev->id_irq != (1 << c)) {
|
||||
if (ia->ia_irq != (1 << c)) {
|
||||
printf("%s: kernel configured irq %d doesn't match board configured irq %d\n",
|
||||
sc->sc_dev.dv_xname, ffs(isa_dev->id_irq) - 1, c);
|
||||
sc->sc_dev.dv_xname, ffs(ia->ia_irq) - 1, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c = (inb(PORT + IE507_MADDR) & 0x1c) + 0xc0;
|
||||
|
||||
if (kvtop(isa_dev->id_maddr) != ((int)c << 12)) {
|
||||
if (kvtop(ia->ia_maddr) != ((int)c << 12)) {
|
||||
printf("%s: kernel configured maddr %x doesn't match board configured maddr %x\n",
|
||||
sc->sc_dev.dv_xname, kvtop(isa_dev->id_maddr),
|
||||
sc->sc_dev.dv_xname, kvtop(ia->ia_maddr),
|
||||
(int)c << 12);
|
||||
return 0;
|
||||
}
|
||||
|
@ -492,11 +486,11 @@ el_probe(isa_dev, sc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!isa_dev->id_msize)
|
||||
isa_dev->id_msize = sc->sc_msize;
|
||||
else if (isa_dev->id_msize != sc->sc_msize) {
|
||||
if (!ia->ia_msize)
|
||||
ia->ia_msize = sc->sc_msize;
|
||||
else if (ia->ia_msize != sc->sc_msize) {
|
||||
printf("%s: kernel configured msize %d doesn't match board configured msize %d\n",
|
||||
sc->sc_dev.dv_xname, isa_dev->id_msize, sc->sc_msize);
|
||||
sc->sc_dev.dv_xname, ia->ia_msize, sc->sc_msize);
|
||||
outb(PORT + IE507_CTRL, EL_CTRL_NRST);
|
||||
return 0;
|
||||
}
|
||||
|
@ -505,23 +499,25 @@ el_probe(isa_dev, sc)
|
|||
sc->chan_attn = el_chan_attn;
|
||||
slel_get_address(sc);
|
||||
|
||||
return 16;
|
||||
ia->ia_iosize = 16;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
|
||||
*/
|
||||
int
|
||||
ieattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
ieattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[isa_dev->id_unit];
|
||||
struct ie_softc *sc = (void *)self;
|
||||
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
|
||||
ifp->if_unit = sc->sc_dev.dv_unit;
|
||||
ifp->if_name = iedriver.name;
|
||||
ifp->if_name = iecd.cd_name;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_output = ether_output;
|
||||
ifp->if_start = iestart;
|
||||
|
@ -570,7 +566,7 @@ int
|
|||
iewatchdog(unit)
|
||||
short unit;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[unit];
|
||||
struct ie_softc *sc = iecd.cd_devs[unit];
|
||||
|
||||
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
|
||||
++sc->sc_arpcom.ac_if.if_oerrors;
|
||||
|
@ -585,7 +581,7 @@ int
|
|||
ieintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[unit];
|
||||
struct ie_softc *sc = iecd.cd_devs[unit];
|
||||
register u_short status;
|
||||
|
||||
status = sc->scb->ie_status;
|
||||
|
@ -1243,7 +1239,7 @@ int
|
|||
iestart(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[ifp->if_unit];
|
||||
struct ie_softc *sc = iecd.cd_devs[ifp->if_unit];
|
||||
struct mbuf *m0, *m;
|
||||
u_char *buffer;
|
||||
u_short len;
|
||||
|
@ -1847,7 +1843,7 @@ ieioctl(ifp, cmd, data)
|
|||
int cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
struct ie_softc *sc = &ie_softc[ifp->if_unit];
|
||||
struct ie_softc *sc = iecd.cd_devs[ifp->if_unit];
|
||||
struct ifaddr *ifa = (struct ifaddr *)data;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
int s, error = 0;
|
||||
|
|
|
@ -46,15 +46,13 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: lpt.c,v 1.14 1994/03/06 17:19:11 mycroft Exp $
|
||||
* $Id: lpt.c,v 1.15 1994/03/29 04:36:08 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Device Driver for AT parallel printer port
|
||||
*/
|
||||
|
||||
#include "lpt.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -70,7 +68,7 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/lptreg.h>
|
||||
|
||||
#define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */
|
||||
|
@ -104,14 +102,14 @@ struct lpt_softc {
|
|||
#define LPT_NOPRIME 0x40 /* don't prime on open */
|
||||
#define LPT_NOINTR 0x80 /* do not use interrupt */
|
||||
u_char sc_control;
|
||||
} lpt_softc[NLPT];
|
||||
};
|
||||
|
||||
int lptprobe __P((struct isa_device *));
|
||||
int lptattach __P((struct isa_device *));
|
||||
int lptprobe();
|
||||
void lptattach();
|
||||
int lptintr __P((int));
|
||||
|
||||
struct isa_driver lptdriver = {
|
||||
lptprobe, lptattach, "lpt"
|
||||
struct cfdriver lptcd = {
|
||||
NULL, "lpt", lptprobe, lptattach, DV_TTY, sizeof(struct lpt_softc)
|
||||
};
|
||||
|
||||
#define LPTUNIT(s) (minor(s) & 0x1f)
|
||||
|
@ -174,10 +172,12 @@ lpt_port_test(port, data, mask)
|
|||
* 3) Set the data and control ports to a value of 0
|
||||
*/
|
||||
int
|
||||
lptprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
lptprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_short port;
|
||||
u_char mask, data;
|
||||
int i;
|
||||
|
@ -226,23 +226,25 @@ lptprobe(isa_dev)
|
|||
outb(iobase + lpt_data, 0);
|
||||
outb(iobase + lpt_control, 0);
|
||||
|
||||
return LPT_NPORTS;
|
||||
ia->ia_iosize = LPT_NPORTS;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
lptattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
lptattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[isa_dev->id_unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
u_short irq = isa_dev->id_irq;
|
||||
struct lpt_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_short irq = ia->ia_irq;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", lptdriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
if (!irq)
|
||||
printf("%s: polled\n", sc->sc_dev.dv_xname);
|
||||
if (irq)
|
||||
printf("\n");
|
||||
else
|
||||
printf(": polled\n");
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_irq = irq;
|
||||
|
@ -266,10 +268,10 @@ lptopen(dev, flag)
|
|||
int error;
|
||||
int spin;
|
||||
|
||||
if (unit >= NLPT)
|
||||
if (unit >= lptcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &lpt_softc[unit];
|
||||
if (!sc->sc_iobase)
|
||||
sc = lptcd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
if (sc->sc_irq == 0 && (flags & LPT_NOINTR) == 0)
|
||||
|
@ -372,7 +374,7 @@ lptclose(dev, flag)
|
|||
int flag;
|
||||
{
|
||||
int unit = LPTUNIT(dev);
|
||||
struct lpt_softc *sc = &lpt_softc[unit];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
|
||||
if (sc->sc_count)
|
||||
|
@ -454,7 +456,7 @@ lptwrite(dev, uio)
|
|||
dev_t dev;
|
||||
struct uio *uio;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[LPTUNIT(dev)];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[LPTUNIT(dev)];
|
||||
size_t n;
|
||||
int error = 0;
|
||||
|
||||
|
@ -483,7 +485,7 @@ int
|
|||
lptintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[unit];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -46,15 +46,13 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: lpt_isa.c,v 1.14 1994/03/06 17:19:11 mycroft Exp $
|
||||
* $Id: lpt_isa.c,v 1.15 1994/03/29 04:36:08 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Device Driver for AT parallel printer port
|
||||
*/
|
||||
|
||||
#include "lpt.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -70,7 +68,7 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/lptreg.h>
|
||||
|
||||
#define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */
|
||||
|
@ -104,14 +102,14 @@ struct lpt_softc {
|
|||
#define LPT_NOPRIME 0x40 /* don't prime on open */
|
||||
#define LPT_NOINTR 0x80 /* do not use interrupt */
|
||||
u_char sc_control;
|
||||
} lpt_softc[NLPT];
|
||||
};
|
||||
|
||||
int lptprobe __P((struct isa_device *));
|
||||
int lptattach __P((struct isa_device *));
|
||||
int lptprobe();
|
||||
void lptattach();
|
||||
int lptintr __P((int));
|
||||
|
||||
struct isa_driver lptdriver = {
|
||||
lptprobe, lptattach, "lpt"
|
||||
struct cfdriver lptcd = {
|
||||
NULL, "lpt", lptprobe, lptattach, DV_TTY, sizeof(struct lpt_softc)
|
||||
};
|
||||
|
||||
#define LPTUNIT(s) (minor(s) & 0x1f)
|
||||
|
@ -174,10 +172,12 @@ lpt_port_test(port, data, mask)
|
|||
* 3) Set the data and control ports to a value of 0
|
||||
*/
|
||||
int
|
||||
lptprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
lptprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_short port;
|
||||
u_char mask, data;
|
||||
int i;
|
||||
|
@ -226,23 +226,25 @@ lptprobe(isa_dev)
|
|||
outb(iobase + lpt_data, 0);
|
||||
outb(iobase + lpt_control, 0);
|
||||
|
||||
return LPT_NPORTS;
|
||||
ia->ia_iosize = LPT_NPORTS;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
lptattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
lptattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[isa_dev->id_unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
u_short irq = isa_dev->id_irq;
|
||||
struct lpt_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
u_short irq = ia->ia_irq;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", lptdriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
if (!irq)
|
||||
printf("%s: polled\n", sc->sc_dev.dv_xname);
|
||||
if (irq)
|
||||
printf("\n");
|
||||
else
|
||||
printf(": polled\n");
|
||||
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_irq = irq;
|
||||
|
@ -266,10 +268,10 @@ lptopen(dev, flag)
|
|||
int error;
|
||||
int spin;
|
||||
|
||||
if (unit >= NLPT)
|
||||
if (unit >= lptcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &lpt_softc[unit];
|
||||
if (!sc->sc_iobase)
|
||||
sc = lptcd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
if (sc->sc_irq == 0 && (flags & LPT_NOINTR) == 0)
|
||||
|
@ -372,7 +374,7 @@ lptclose(dev, flag)
|
|||
int flag;
|
||||
{
|
||||
int unit = LPTUNIT(dev);
|
||||
struct lpt_softc *sc = &lpt_softc[unit];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
|
||||
if (sc->sc_count)
|
||||
|
@ -454,7 +456,7 @@ lptwrite(dev, uio)
|
|||
dev_t dev;
|
||||
struct uio *uio;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[LPTUNIT(dev)];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[LPTUNIT(dev)];
|
||||
size_t n;
|
||||
int error = 0;
|
||||
|
||||
|
@ -483,7 +485,7 @@ int
|
|||
lptintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct lpt_softc *sc = &lpt_softc[unit];
|
||||
struct lpt_softc *sc = lptcd.cd_devs[unit];
|
||||
u_short iobase = sc->sc_iobase;
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -35,13 +35,11 @@
|
|||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mcd.c,v 1.7 1994/03/06 17:19:13 mycroft Exp $
|
||||
* $Id: mcd.c,v 1.8 1994/03/29 04:36:11 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";*/
|
||||
|
||||
#include "mcd.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -63,7 +61,7 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/mcdreg.h>
|
||||
|
||||
#ifndef MCDDEBUG
|
||||
|
@ -80,13 +78,12 @@
|
|||
/* flags */
|
||||
#define MCDOPEN 0x0001 /* device opened */
|
||||
#define MCDVALID 0x0002 /* parameters loaded */
|
||||
#define MCDINIT 0x0004 /* device is init'd */
|
||||
#define MCDWAIT 0x0008 /* waiting for something */
|
||||
#define MCDLABEL 0x0010 /* label is read */
|
||||
#define MCDREADRAW 0x0020 /* read raw mode (2352 bytes) */
|
||||
#define MCDVOLINFO 0x0040 /* already read volinfo */
|
||||
#define MCDTOC 0x0080 /* already read toc */
|
||||
#define MCDMBXBSY 0x0100 /* local mbx is busy */
|
||||
#define MCDWAIT 0x0004 /* waiting for something */
|
||||
#define MCDLABEL 0x0008 /* label is read */
|
||||
#define MCDREADRAW 0x0010 /* read raw mode (2352 bytes) */
|
||||
#define MCDVOLINFO 0x0020 /* already read volinfo */
|
||||
#define MCDTOC 0x0040 /* already read toc */
|
||||
#define MCDMBXBSY 0x0080 /* local mbx is busy */
|
||||
|
||||
/* status */
|
||||
#define MCDAUDIOBSY MCD_ST_AUDIOBSY /* playing audio */
|
||||
|
@ -129,11 +126,9 @@ struct mcd_softc {
|
|||
short debug;
|
||||
struct buf head; /* head of buf queue */
|
||||
struct mcd_mbx mbx;
|
||||
} mcd_softc[NMCD];
|
||||
};
|
||||
|
||||
/* prototypes */
|
||||
int mcdprobe __P((struct isa_device *));
|
||||
int mcdattach __P((struct isa_device *));
|
||||
int mcdopen __P((dev_t));
|
||||
int mcdclose __P((dev_t));
|
||||
int mcd_start __P((struct mcd_softc *));
|
||||
|
@ -166,8 +161,11 @@ int mcd_play __P((struct mcd_softc *, struct mcd_read2 *));
|
|||
int mcd_pause __P((struct mcd_softc *));
|
||||
int mcd_resume __P((struct mcd_softc *));
|
||||
|
||||
struct isa_driver mcddriver = {
|
||||
mcdprobe, mcdattach, "mcd"
|
||||
int mcdprobe();
|
||||
void mcdattach();
|
||||
|
||||
struct cfdriver mcdcd = {
|
||||
NULL, "mcd", mcdprobe, mcdattach, DV_DISK, sizeof(struct mcd_softc)
|
||||
};
|
||||
|
||||
#define mcd_put(port,byte) outb(port,byte)
|
||||
|
@ -194,18 +192,20 @@ struct isa_driver mcddriver = {
|
|||
#define MCD_S_WAITMODE 3
|
||||
#define MCD_S_WAITREAD 4
|
||||
|
||||
int
|
||||
mcdattach(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
void
|
||||
mcdattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct mcd_softc *sc = &mcd_softc[isa_dev->id_unit];
|
||||
struct mcd_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
#ifdef notyet
|
||||
/* Wire controller for interrupts and DMA. */
|
||||
mcd_configure(cd);
|
||||
mcd_configure(sc);
|
||||
#endif
|
||||
|
||||
sc->flags = MCDINIT;
|
||||
sc->flags = 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -216,10 +216,10 @@ mcdopen(dev)
|
|||
struct mcd_softc *sc;
|
||||
|
||||
unit = MCDUNIT(dev);
|
||||
if (unit >= NMCD)
|
||||
if (unit >= mcdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
sc = &mcd_softc[unit];
|
||||
if (!sc->iobase || !(sc->flags & MCDINIT))
|
||||
sc = mcdcd.cd_devs[unit];
|
||||
if (!sc)
|
||||
return ENXIO;
|
||||
|
||||
part = MCDPART(dev);
|
||||
|
@ -265,7 +265,7 @@ mcdclose(dev)
|
|||
|
||||
unit = MCDUNIT(dev);
|
||||
part = MCDPART(dev);
|
||||
sc = &mcd_softc[unit];
|
||||
sc = mcdcd.cd_devs[unit];
|
||||
|
||||
/* Get status. */
|
||||
mcd_getstat(sc, 1);
|
||||
|
@ -282,7 +282,7 @@ void
|
|||
mcdstrategy(bp)
|
||||
struct buf *bp;
|
||||
{
|
||||
struct mcd_softc *sc = &mcd_softc[MCDUNIT(bp->b_dev)];
|
||||
struct mcd_softc *sc = mcdcd.cd_devs[MCDUNIT(bp->b_dev)];
|
||||
struct buf *qp;
|
||||
int s;
|
||||
|
||||
|
@ -393,7 +393,7 @@ mcdioctl(dev, cmd, addr, flags, p)
|
|||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
struct mcd_softc *sc = &mcd_softc[MCDUNIT(dev)];
|
||||
struct mcd_softc *sc = mcdcd.cd_devs[MCDUNIT(dev)];
|
||||
|
||||
if (!(sc->flags & MCDVALID))
|
||||
return EIO;
|
||||
|
@ -494,7 +494,7 @@ mcdsize(dev)
|
|||
dev_t dev;
|
||||
{
|
||||
int size;
|
||||
struct mcd_softc *sc = &mcd_softc[MCDUNIT(dev)];
|
||||
struct mcd_softc *sc = mcdcd.cd_devs[MCDUNIT(dev)];
|
||||
|
||||
if (mcd_volinfo(sc) >= 0) {
|
||||
sc->blksize = MCDBLK;
|
||||
|
@ -529,22 +529,19 @@ mcd_configure(sc)
|
|||
}
|
||||
|
||||
int
|
||||
mcdprobe(isa_dev)
|
||||
struct isa_device *isa_dev;
|
||||
mcdprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
int unit = isa_dev->id_unit;
|
||||
struct mcd_softc *sc = &mcd_softc[unit];
|
||||
u_short iobase = isa_dev->id_iobase;
|
||||
struct mcd_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
int i;
|
||||
int st, check;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(sc->sc_dev.dv_xname, "%s%d", mcddriver.name, isa_dev->id_unit);
|
||||
sc->sc_dev.dv_unit = isa_dev->id_unit;
|
||||
|
||||
#ifdef notyet
|
||||
/* Get irq/drq configuration word. */
|
||||
sc->config = irqs[isa_dev->id_irq];
|
||||
sc->config = irqs[ia->ia_irq];
|
||||
#endif
|
||||
sc->iobase = iobase;
|
||||
|
||||
|
@ -576,7 +573,7 @@ mcdprobe(isa_dev)
|
|||
* driven routines mcd_getreply etc. rather than arbitrary delays.
|
||||
*/
|
||||
|
||||
delay (2000);
|
||||
delay(2000);
|
||||
outb(iobase + mcd_command, MCD_CMDCONTINFO);
|
||||
i = mcd_getreply(sc, DELAY_GETREPLY);
|
||||
|
||||
|
@ -614,7 +611,9 @@ mcdprobe(isa_dev)
|
|||
#ifdef DEBUG
|
||||
printf("Mitsumi drive detected\n");
|
||||
#endif
|
||||
return 4;
|
||||
ia->ia_iosize = 4;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -812,7 +811,7 @@ int
|
|||
mcdintr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct mcd_softc *sc = &mcd_softc[unit];
|
||||
struct mcd_softc *sc = mcdcd.cd_devs[unit];
|
||||
u_short iobase = sc->iobase;
|
||||
|
||||
MCD_TRACE("stray interrupt xfer=0x%x\n", inb(iobase + mcd_xfer),
|
||||
|
@ -838,7 +837,7 @@ mcd_doread(state, mbxin)
|
|||
struct mcd_mbx *mbxin;
|
||||
{
|
||||
struct mcd_mbx *mbx = (state != MCD_S_BEGIN) ? mbxsave : mbxin;
|
||||
struct mcd_softc *sc = &mcd_softc[mbx->unit];
|
||||
struct mcd_softc *sc = mcdcd.cd_devs[mbx->unit];
|
||||
u_short iobase = mbx->iobase;
|
||||
struct buf *bp = mbx->bp;
|
||||
|
||||
|
|
395
sys/dev/isa/sb.c
395
sys/dev/isa/sb.c
|
@ -30,23 +30,21 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: sb.c,v 1.5 1994/03/06 17:19:16 mycroft Exp $
|
||||
* $Id: sb.c,v 1.6 1994/03/29 04:36:26 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include "sb.h"
|
||||
#if NSB > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
|
||||
#include "sbreg.h"
|
||||
|
@ -66,15 +64,14 @@
|
|||
* most basic communications with the sb card.
|
||||
*/
|
||||
struct sb_softc {
|
||||
#ifdef NEWCONFIG
|
||||
struct device sc_dev; /* base device */
|
||||
struct isadev sc_id; /* ISA device */
|
||||
struct intrhand sc_ih; /* interrupt vectoring */
|
||||
#endif
|
||||
|
||||
u_short sc_open; /* reference count of open calls */
|
||||
u_short sc_dmachan; /* dma channel */
|
||||
u_long sc_locked; /* true when doing HS DMA */
|
||||
u_long sc_base; /* I/O port base address */
|
||||
u_short sc_locked; /* true when doing HS DMA */
|
||||
u_short sc_iobase; /* I/O port base address */
|
||||
u_short sc_adacmode; /* low/high speed mode indicator */
|
||||
#define SB_ADAC_LS 0
|
||||
#define SB_ADAC_HS 1
|
||||
|
@ -85,21 +82,17 @@ struct sb_softc {
|
|||
void *sc_arg; /* arg for sc_intr() */
|
||||
};
|
||||
|
||||
int sbreset(u_long);
|
||||
int sbreset __P((struct sb_softc *));
|
||||
void sb_spkron __P((struct sb_softc *));
|
||||
void sb_spkroff __P((struct sb_softc *));
|
||||
|
||||
void sb_spkron(struct sb_softc *);
|
||||
void sb_spkroff(struct sb_softc *);
|
||||
static int wdsp(u_short iobase, int v);
|
||||
static int rdsp(u_short iobase);
|
||||
|
||||
static int wdsp(u_long base, int v);
|
||||
static int rdsp(u_long base);
|
||||
|
||||
/* XXX */
|
||||
#define splsb splhigh
|
||||
/* XXX */
|
||||
struct sb_softc *sb_softc;
|
||||
#define splsb splhigh /* XXX */
|
||||
struct sb_softc *sb_softc; /* XXX */
|
||||
|
||||
#ifndef NEWCONFIG
|
||||
struct sb_softc sb_softcs[NSB];
|
||||
#define at_dma(flags, ptr, cc, chan) isa_dmastart(flags, ptr, cc, chan)
|
||||
#endif
|
||||
|
||||
|
@ -109,60 +102,73 @@ struct {
|
|||
int wmidi;
|
||||
} sberr;
|
||||
|
||||
int sbintr __P((int));
|
||||
int sbprobe();
|
||||
void sbattach();
|
||||
#ifdef NEWCONFIG
|
||||
int sbintr(struct sb_softc *);
|
||||
int sbprobe(struct device *, struct cfdata *, void *);
|
||||
void sbattach(struct device *, struct device *, void *);
|
||||
void sbforceintr(void *);
|
||||
#endif
|
||||
|
||||
struct cfdriver sbcd =
|
||||
{ NULL, "sb", sbprobe, sbattach, sizeof(struct sb_softc) };
|
||||
struct cfdriver sbcd = {
|
||||
NULL, "sb", sbprobe, sbattach, DV_DULL, sizeof(struct sb_softc)
|
||||
};
|
||||
|
||||
int
|
||||
sbprobe(struct device *parent, struct cfdata *cf, void *aux)
|
||||
sbprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
register struct isa_attach_args *ia = (struct isa_attach_args *)aux;
|
||||
register int base = ia->ia_iobase;
|
||||
register struct sb_softc *sc = (void *)self;
|
||||
register struct isa_attach_args *ia = aux;
|
||||
register u_short iobase = ia->ia_iobase;
|
||||
|
||||
if (!SB_BASE_VALID(base)) {
|
||||
printf("sb: configured dma chan %d invalid\n", ia->ia_drq);
|
||||
return (0);
|
||||
if (!SB_BASE_VALID(ia->ia_iobase)) {
|
||||
printf("sb: configured iobase %d invalid\n", ia->ia_iobase);
|
||||
return 0;
|
||||
}
|
||||
ia->ia_iosize = SB_NPORT;
|
||||
if (sbreset(base) < 0) {
|
||||
sc->sc_iobase = iobase;
|
||||
if (sbreset(sc) < 0) {
|
||||
printf("sb: couldn't reset card\n");
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Cannot auto-discover DMA channel.
|
||||
*/
|
||||
if (!SB_DRQ_VALID(ia->ia_drq)) {
|
||||
printf("sb: configured dma chan %d invalid\n", ia->ia_drq);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
#ifdef NEWCONFIG
|
||||
/*
|
||||
* If the IRQ wasn't compiled in, auto-detect it.
|
||||
*/
|
||||
if (ia->ia_irq == IRQUNK) {
|
||||
ia->ia_irq = isa_discoverintr(sbforceintr, aux);
|
||||
sbreset(base);
|
||||
sbreset(iobase);
|
||||
if (!SB_IRQ_VALID(ia->ia_irq)) {
|
||||
printf("sb: couldn't auto-detect interrupt");
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
} else if (!SB_IRQ_VALID(ia->ia_irq)) {
|
||||
} else
|
||||
#endif
|
||||
if (!SB_IRQ_VALID(ia->ia_irq)) {
|
||||
int irq = ffs(ia->ia_irq) - 1;
|
||||
printf("sb: configured irq %d invalid\n", irq);
|
||||
return 0;
|
||||
}
|
||||
return (15);
|
||||
ia->ia_iosize = SB_NPORT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef NEWCONFIG
|
||||
void
|
||||
sbforceintr(void *arg)
|
||||
sbforceintr(aux)
|
||||
void *aux;
|
||||
{
|
||||
static char dmabuf;
|
||||
struct isa_attach_args *ia = (struct isa_attach_args *)arg;
|
||||
int base = ia->ia_iobase;
|
||||
struct isa_attach_args *ia = aux;
|
||||
u_short iobase = ia->ia_iobase;
|
||||
|
||||
/*
|
||||
* Set up a DMA read of one byte.
|
||||
* XXX Note that at this point we haven't called
|
||||
|
@ -175,11 +181,12 @@ sbforceintr(void *arg)
|
|||
* never need the buffer anyway.)
|
||||
*/
|
||||
at_dma(1, &dmabuf, 1, ia->ia_drq);
|
||||
if (wdsp(base, SB_DSP_RDMA) == 0) {
|
||||
(void)wdsp(base, 0);
|
||||
(void)wdsp(base, 0);
|
||||
if (wdsp(iobase, SB_DSP_RDMA) == 0) {
|
||||
(void)wdsp(iobase, 0);
|
||||
(void)wdsp(iobase, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sbattach(parent, self, aux)
|
||||
|
@ -188,15 +195,17 @@ sbattach(parent, self, aux)
|
|||
{
|
||||
register struct sb_softc *sc = (struct sb_softc *)self;
|
||||
struct isa_attach_args *ia = (struct isa_attach_args *)aux;
|
||||
register int base = ia->ia_iobase;
|
||||
register u_short iobase = ia->ia_iobase;
|
||||
register int vers;
|
||||
|
||||
/* XXX */
|
||||
sb_softc = sc;
|
||||
|
||||
sc->sc_base = base;
|
||||
sc->sc_iobase = iobase;
|
||||
sc->sc_dmachan = ia->ia_drq;
|
||||
sc->sc_locked = 0;
|
||||
|
||||
#ifdef NEWCONFIG
|
||||
isa_establish(&sc->sc_id, &sc->sc_dev);
|
||||
sc->sc_ih.ih_fun = sbintr;
|
||||
sc->sc_ih.ih_arg = (void *)sc;
|
||||
|
@ -214,101 +223,43 @@ sbattach(parent, self, aux)
|
|||
* is plenty long enough to amortize any fixed time overhead.
|
||||
*/
|
||||
at_setup_dmachan(sc->sc_dmachan, NBPG);
|
||||
|
||||
vers = sbversion(base);
|
||||
printf(" dsp v%d.%d\n", vers >> 8, vers & 0xff);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NEWCONFIG
|
||||
int sbintr(int unit);
|
||||
int sbprobe(struct isa_device *dev);
|
||||
int sbattach(struct isa_device *dev);
|
||||
|
||||
struct isa_driver sbdriver = { sbprobe, sbattach, "sb" };
|
||||
|
||||
int
|
||||
sbprobe(struct isa_device *dev)
|
||||
{
|
||||
register int base = dev->id_iobase;
|
||||
|
||||
if (!SB_BASE_VALID(base)) {
|
||||
printf("sb: configured dma chan %d invalid\n", dev->id_drq);
|
||||
return (0);
|
||||
}
|
||||
if (sbreset(base) < 0) {
|
||||
printf("sb: couldn't reset card\n");
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* Cannot auto-discover DMA channel.
|
||||
*/
|
||||
if (!SB_DRQ_VALID(dev->id_drq)) {
|
||||
printf("sb: configured dma chan %d invalid\n", dev->id_drq);
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* If the IRQ wasn't compiled in, auto-detect it.
|
||||
*/
|
||||
if (dev->id_irq == 0) {
|
||||
printf("sb: no irq configured\n");
|
||||
return (0);
|
||||
} else if (!SB_IRQ_VALID(dev->id_irq)) {
|
||||
int irq = ffs(dev->id_irq) - 1;
|
||||
printf("sb: configured irq %d invalid\n", irq);
|
||||
return (0);
|
||||
}
|
||||
return (15);
|
||||
vers = sbversion(sc);
|
||||
printf(": dsp v%d.%d\n", vers >> 8, vers & 0xff);
|
||||
}
|
||||
|
||||
#define UNIT(x) (minor(x) & 0xf)
|
||||
|
||||
int
|
||||
sbattach(struct isa_device *dev)
|
||||
{
|
||||
int unit = UNIT(dev->id_unit);
|
||||
register struct sb_softc *sc = &sb_softcs[unit];
|
||||
register int base = dev->id_iobase;
|
||||
register int vers;
|
||||
|
||||
/* XXX */
|
||||
sb_softc = sc;
|
||||
|
||||
sc->sc_base = base;
|
||||
sc->sc_dmachan = dev->id_drq;
|
||||
sc->sc_locked = 0;
|
||||
|
||||
vers = sbversion(base);
|
||||
printf("sb%d: dsp v%d.%d\n", unit, vers >> 8, vers & 0xff);
|
||||
}
|
||||
#endif
|
||||
#define SBUNIT(x) (minor(x) & 0xf)
|
||||
|
||||
struct sb_softc *
|
||||
sbopen()
|
||||
{
|
||||
/* XXXX */
|
||||
struct sb_softc *sc = sb_softc;
|
||||
|
||||
if (sc == 0)
|
||||
return 0;
|
||||
|
||||
if (sc->sc_open == 0 && sbreset(sc->sc_base) == 0) {
|
||||
if (sc->sc_open == 0 && sbreset(sc) == 0) {
|
||||
sc->sc_open = 1;
|
||||
sc->sc_mintr = 0;
|
||||
sc->sc_intr = 0;
|
||||
return (sc);
|
||||
return sc;
|
||||
}
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sbclose(struct sb_softc *sc)
|
||||
sbclose(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
|
||||
sc->sc_open = 0;
|
||||
sb_spkroff(sc);
|
||||
sc->sc_intr = 0;
|
||||
sc->sc_mintr = 0;
|
||||
/* XXX this will turn off any dma */
|
||||
sbreset(sc->sc_base);
|
||||
sbreset(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -317,35 +268,35 @@ sbclose(struct sb_softc *sc)
|
|||
* polling loop and wait until it can take the byte.
|
||||
*/
|
||||
static int
|
||||
wdsp(u_long base, int v)
|
||||
wdsp(u_short iobase, int v)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 100; --i >= 0; ) {
|
||||
if ((inb(base + SBP_DSP_WSTAT) & SB_DSP_BUSY) != 0)
|
||||
if ((inb(iobase + SBP_DSP_WSTAT) & SB_DSP_BUSY) != 0)
|
||||
continue;
|
||||
outb(base + SBP_DSP_WRITE, v);
|
||||
return (0);
|
||||
outb(iobase + SBP_DSP_WRITE, v);
|
||||
return 0;
|
||||
}
|
||||
++sberr.wdsp;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a byte from the DSP, using polling.
|
||||
*/
|
||||
int
|
||||
rdsp(u_long base)
|
||||
rdsp(u_short iobase)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 100; --i >= 0; ) {
|
||||
if ((inb(base + SBP_DSP_RSTAT) & SB_DSP_READY) == 0)
|
||||
if ((inb(iobase + SBP_DSP_RSTAT) & SB_DSP_READY) == 0)
|
||||
continue;
|
||||
return (inb(base + SBP_DSP_READ));
|
||||
return inb(iobase + SBP_DSP_READ);
|
||||
}
|
||||
++sberr.rdsp;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -353,20 +304,23 @@ rdsp(u_long base)
|
|||
* Return non-zero if the card isn't detected.
|
||||
*/
|
||||
int
|
||||
sbreset(register u_long base)
|
||||
sbreset(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
register u_short iobase = sc->sc_iobase;
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* See SBK, section 11.3.
|
||||
* We pulse a reset signal into the card.
|
||||
* Gee, what a brilliant hardware design.
|
||||
*/
|
||||
outb(base + SBP_DSP_RESET, 1);
|
||||
outb(iobase + SBP_DSP_RESET, 1);
|
||||
delay(3);
|
||||
outb(base + SBP_DSP_RESET, 0);
|
||||
if (rdsp(base) != SB_MAGIC)
|
||||
return (-1);
|
||||
return (0);
|
||||
outb(iobase + SBP_DSP_RESET, 0);
|
||||
if (rdsp(iobase) != SB_MAGIC)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -380,9 +334,12 @@ sbreset(register u_long base)
|
|||
* they designed this card.
|
||||
*/
|
||||
void
|
||||
sb_spkron(struct sb_softc *sc)
|
||||
sb_spkron(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
(void)wdsp(sc->sc_base, SB_DSP_SPKR_ON);
|
||||
|
||||
(void)wdsp(sc->sc_iobase, SB_DSP_SPKR_ON);
|
||||
/* XXX bogus */
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
@ -390,9 +347,11 @@ sb_spkron(struct sb_softc *sc)
|
|||
* Turn off the speaker; see comment above.
|
||||
*/
|
||||
void
|
||||
sb_spkroff(struct sb_softc *sc)
|
||||
sb_spkroff(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
(void)wdsp(sc->sc_base, SB_DSP_SPKR_OFF);
|
||||
|
||||
(void)wdsp(sc->sc_iobase, SB_DSP_SPKR_OFF);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -400,14 +359,16 @@ sb_spkroff(struct sb_softc *sc)
|
|||
* in high byte, and minor code in low byte.
|
||||
*/
|
||||
int
|
||||
sbversion(register u_long base)
|
||||
sbversion(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
register u_short iobase = sc->sc_iobase;
|
||||
int v;
|
||||
|
||||
if (wdsp(base, SB_DSP_VERSION) < 0)
|
||||
return (0);
|
||||
v = rdsp(base) << 8;
|
||||
v |= rdsp(base);
|
||||
if (wdsp(iobase, SB_DSP_VERSION) < 0)
|
||||
return 0;
|
||||
v = rdsp(iobase) << 8;
|
||||
v |= rdsp(iobase);
|
||||
return ((v >= 0) ? v : 0);
|
||||
}
|
||||
|
||||
|
@ -416,18 +377,22 @@ sbversion(register u_long base)
|
|||
* resumed with sb_contdma().
|
||||
*/
|
||||
void
|
||||
sb_haltdma(struct sb_softc *sc)
|
||||
sb_haltdma(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
|
||||
if (sc->sc_locked)
|
||||
sbreset(sc->sc_base);
|
||||
sbreset(sc);
|
||||
else
|
||||
(void)wdsp(sc->sc_base, SB_DSP_HALT);
|
||||
(void)wdsp(sc->sc_iobase, SB_DSP_HALT);
|
||||
}
|
||||
|
||||
void
|
||||
sb_contdma(struct sb_softc *sc)
|
||||
sb_contdma(sc)
|
||||
struct sb_softc *sc;
|
||||
{
|
||||
(void)wdsp(sc->sc_base, SB_DSP_CONT);
|
||||
|
||||
(void)wdsp(sc->sc_iobase, SB_DSP_CONT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -475,7 +440,10 @@ sb_contdma(struct sb_softc *sc)
|
|||
* so isdac indicates output, and !isdac indicates input.
|
||||
*/
|
||||
int
|
||||
sb_srtotc(int sr, int *mode, int isdac)
|
||||
sb_srtotc(sr, mode, isdac)
|
||||
int sr;
|
||||
int *mode;
|
||||
int isdac;
|
||||
{
|
||||
register int tc = 256 - 1000000 / sr;
|
||||
|
||||
|
@ -499,7 +467,7 @@ sb_srtotc(int sr, int *mode, int isdac)
|
|||
tc = SB_ADC_HS_MAX;
|
||||
}
|
||||
}
|
||||
return (tc);
|
||||
return tc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -507,96 +475,112 @@ sb_srtotc(int sr, int *mode, int isdac)
|
|||
* See SBK, section 12.
|
||||
*/
|
||||
int
|
||||
sb_tctosr(int tc)
|
||||
sb_tctosr(tc)
|
||||
int tc;
|
||||
{
|
||||
return (1000000 / (256 - tc));
|
||||
}
|
||||
|
||||
int
|
||||
sb_set_sr(register struct sb_softc *sc, u_long *sr, int isdac)
|
||||
sb_set_sr(sc, sr, isdac)
|
||||
register struct sb_softc *sc;
|
||||
u_long *sr;
|
||||
int isdac;
|
||||
{
|
||||
register int tc;
|
||||
int mode;
|
||||
|
||||
tc = sb_srtotc(*sr, &mode, isdac);
|
||||
if (wdsp(sc->sc_base, SB_DSP_TIMECONST) < 0 ||
|
||||
wdsp(sc->sc_base, tc) < 0)
|
||||
return (-1);
|
||||
if (wdsp(sc->sc_iobase, SB_DSP_TIMECONST) < 0 ||
|
||||
wdsp(sc->sc_iobase, tc) < 0)
|
||||
return -1;
|
||||
|
||||
*sr = sb_tctosr(tc);
|
||||
sc->sc_adacmode = mode;
|
||||
sc->sc_adactc = tc;
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sb_round_sr(u_long sr, int isdac)
|
||||
sb_round_sr(sr, isdac)
|
||||
u_long sr;
|
||||
int isdac;
|
||||
{
|
||||
int mode, tc;
|
||||
|
||||
tc = sb_srtotc(sr, &mode, isdac);
|
||||
return (sb_tctosr(tc));
|
||||
return sb_tctosr(tc);
|
||||
}
|
||||
|
||||
int
|
||||
sb_dma_input(struct sb_softc *sc, void *p, int cc, void (*intr)(), void *arg)
|
||||
sb_dma_input(sc, p, cc, intr, arg)
|
||||
struct sb_softc *sc;
|
||||
void *p;
|
||||
int cc;
|
||||
void (*intr)();
|
||||
void *arg;
|
||||
{
|
||||
register int base;
|
||||
register u_short iobase;
|
||||
|
||||
at_dma(1, p, cc, sc->sc_dmachan);
|
||||
sc->sc_intr = intr;
|
||||
sc->sc_arg = arg;
|
||||
base = sc->sc_base;
|
||||
iobase = sc->sc_iobase;
|
||||
--cc;
|
||||
if (sc->sc_adacmode == SB_ADAC_LS) {
|
||||
if (wdsp(base, SB_DSP_RDMA) < 0 ||
|
||||
wdsp(base, cc) < 0 ||
|
||||
wdsp(base, cc >> 8) < 0) {
|
||||
sbreset(sc->sc_base);
|
||||
return (EIO);
|
||||
if (wdsp(iobase, SB_DSP_RDMA) < 0 ||
|
||||
wdsp(iobase, cc) < 0 ||
|
||||
wdsp(iobase, cc >> 8) < 0) {
|
||||
sbreset(sc);
|
||||
return EIO;
|
||||
}
|
||||
} else {
|
||||
if (wdsp(base, SB_DSP_BLOCKSIZE) < 0 ||
|
||||
wdsp(base, cc) < 0 ||
|
||||
wdsp(base, cc >> 8) < 0 ||
|
||||
wdsp(base, SB_DSP_HS_INPUT) < 0) {
|
||||
sbreset(sc->sc_base);
|
||||
return (EIO);
|
||||
if (wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 ||
|
||||
wdsp(iobase, cc) < 0 ||
|
||||
wdsp(iobase, cc >> 8) < 0 ||
|
||||
wdsp(iobase, SB_DSP_HS_INPUT) < 0) {
|
||||
sbreset(sc);
|
||||
return EIO;
|
||||
}
|
||||
sc->sc_locked = 1;
|
||||
}
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sb_dma_output(struct sb_softc *sc, void *p, int cc, void (*intr)(), void *arg)
|
||||
sb_dma_output(sc, p, cc, intr, arg)
|
||||
struct sb_softc *sc;
|
||||
void *p;
|
||||
int cc;
|
||||
void (*intr)();
|
||||
void *arg;
|
||||
{
|
||||
register int base;
|
||||
register u_short iobase;
|
||||
|
||||
at_dma(0, p, cc, sc->sc_dmachan);
|
||||
sc->sc_intr = intr;
|
||||
sc->sc_arg = arg;
|
||||
base = sc->sc_base;
|
||||
iobase = sc->sc_iobase;
|
||||
--cc;
|
||||
if (sc->sc_adacmode == SB_ADAC_LS) {
|
||||
if (wdsp(base, SB_DSP_WDMA) < 0 ||
|
||||
wdsp(base, cc) < 0 ||
|
||||
wdsp(base, cc >> 8) < 0) {
|
||||
sbreset(sc->sc_base);
|
||||
return (EIO);
|
||||
if (wdsp(iobase, SB_DSP_WDMA) < 0 ||
|
||||
wdsp(iobase, cc) < 0 ||
|
||||
wdsp(iobase, cc >> 8) < 0) {
|
||||
sbreset(sc);
|
||||
return EIO;
|
||||
}
|
||||
} else {
|
||||
if (wdsp(base, SB_DSP_BLOCKSIZE) < 0 ||
|
||||
wdsp(base, cc) < 0 ||
|
||||
wdsp(base, cc >> 8) < 0 ||
|
||||
wdsp(base, SB_DSP_HS_OUTPUT) < 0) {
|
||||
sbreset(sc->sc_base);
|
||||
return (EIO);
|
||||
if (wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 ||
|
||||
wdsp(iobase, cc) < 0 ||
|
||||
wdsp(iobase, cc >> 8) < 0 ||
|
||||
wdsp(iobase, SB_DSP_HS_OUTPUT) < 0) {
|
||||
sbreset(sc);
|
||||
return EIO;
|
||||
}
|
||||
sc->sc_locked = 1;
|
||||
}
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -606,28 +590,23 @@ sb_dma_output(struct sb_softc *sc, void *p, int cc, void (*intr)(), void *arg)
|
|||
* completion of a dma reception. The three modes are mutually
|
||||
* exclusive so we know a priori which event has occurred.
|
||||
*/
|
||||
#ifdef NEWCONFIG
|
||||
int
|
||||
sbintr(struct sb_softc *sc)
|
||||
sbintr(unit)
|
||||
int unit;
|
||||
{
|
||||
#else
|
||||
int
|
||||
sbintr(int unit)
|
||||
{
|
||||
register struct sb_softc *sc = &sb_softcs[UNIT(unit)];
|
||||
#endif
|
||||
register struct sb_softc *sc = sbcd.cd_devs[SBUNIT(unit)];
|
||||
|
||||
sc->sc_locked = 0;
|
||||
/* clear interrupt */
|
||||
inb(sc->sc_base + SBP_DSP_RSTAT);
|
||||
inb(sc->sc_iobase + SBP_DSP_RSTAT);
|
||||
if (sc->sc_mintr != 0) {
|
||||
int c = rdsp(sc->sc_base);
|
||||
int c = rdsp(sc->sc_iobase);
|
||||
(*sc->sc_mintr)(sc->sc_arg, c);
|
||||
} else if(sc->sc_intr != 0) {
|
||||
} else if (sc->sc_intr != 0)
|
||||
(*sc->sc_intr)(sc->sc_arg);
|
||||
} else
|
||||
return (0);
|
||||
return (1);
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -636,17 +615,19 @@ sbintr(int unit)
|
|||
* which allows only midi I/O; the card must be reset
|
||||
* to leave this mode. Unfortunately, the card does not
|
||||
* use transmit interrupts, so bytes must be output
|
||||
|
||||
|
||||
* using polling. To keep the polling overhead to a
|
||||
* minimum, output should be driven off a timer.
|
||||
* This is a little tricky since only 320us separate
|
||||
* consecutive midi bytes.
|
||||
*/
|
||||
void
|
||||
sb_set_midi_mode(struct sb_softc *sc, void (*intr)(), void *arg)
|
||||
sb_set_midi_mode(sc, intr, arg)
|
||||
struct sb_softc *sc;
|
||||
void (*intr)();
|
||||
void *arg;
|
||||
{
|
||||
wdsp(sc->sc_base, SB_MIDI_UART_INTR);
|
||||
|
||||
wdsp(sc->sc_iobase, SB_MIDI_UART_INTR);
|
||||
sc->sc_mintr = intr;
|
||||
sc->sc_intr = 0;
|
||||
sc->sc_arg = arg;
|
||||
|
@ -656,9 +637,11 @@ sb_set_midi_mode(struct sb_softc *sc, void (*intr)(), void *arg)
|
|||
* Write a byte to the midi port, when in midi uart mode.
|
||||
*/
|
||||
void
|
||||
sb_midi_output(struct sb_softc *sc, int v)
|
||||
sb_midi_output(sc, v)
|
||||
struct sb_softc *sc;
|
||||
int v;
|
||||
{
|
||||
if (wdsp(sc->sc_base, v) < 0)
|
||||
|
||||
if (wdsp(sc->sc_iobase, v) < 0)
|
||||
++sberr.wmidi;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* From: Header: sbreg.h,v 1.3 93/07/18 14:07:28 mccanne Exp (LBL)
|
||||
* $Id: sbreg.h,v 1.1 1994/01/09 19:35:10 cgd Exp $
|
||||
* $Id: sbreg.h,v 1.2 1994/03/29 04:36:28 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -141,7 +141,7 @@
|
|||
*/
|
||||
#define SB_IRQ_VALID(mask) ((mask) & 0x00ac) /* IRQ 2,3,5,7 */
|
||||
#define SB_DRQ_VALID(chan) ((chan) == 1)
|
||||
#define SB_BASE_VALID(chan) ((base) == 0x220 || (base) == 0x240)
|
||||
#define SB_BASE_VALID(base) ((base) == 0x220 || (base) == 0x240)
|
||||
|
||||
#define SB_INPUT_RATE 0
|
||||
#define SB_OUTPUT_RATE 1
|
||||
|
|
211
sys/dev/isa/wd.c
211
sys/dev/isa/wd.c
|
@ -35,14 +35,11 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
|
||||
* $Id: wd.c,v 1.73 1994/03/12 22:36:40 mycroft Exp $
|
||||
* $Id: wd.c,v 1.74 1994/03/29 04:36:30 mycroft Exp $
|
||||
*/
|
||||
|
||||
#define INSTRUMENT /* instrumentation stuff by Brad Parker */
|
||||
|
||||
#include "wd.h"
|
||||
#if NWDC > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dkbad.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -68,7 +65,10 @@
|
|||
#include <machine/pio.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#ifndef NEWCONFIG
|
||||
#include <i386/isa/isa_device.h>
|
||||
#endif
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/wdreg.h>
|
||||
|
||||
|
@ -111,8 +111,7 @@ struct wd_softc {
|
|||
long sc_mbcount; /* total byte count left */
|
||||
short sc_skip; /* blocks already transferred */
|
||||
short sc_mskip; /* blocks already transferred for multi */
|
||||
char sc_unit; /* physical unit number */
|
||||
char sc_lunit; /* logical unit number */
|
||||
char sc_drive; /* physical unit number */
|
||||
char sc_state; /* control state */
|
||||
|
||||
u_long sc_copenpart; /* character units open on this drive */
|
||||
|
@ -128,7 +127,7 @@ struct wd_softc {
|
|||
struct disklabel sc_label; /* device configuration data */
|
||||
struct cpu_disklabel sc_cpulabel;
|
||||
long sc_badsect[127]; /* 126 plus trailing -1 marker */
|
||||
} *wd_softc[NWD];
|
||||
};
|
||||
|
||||
struct wdc_softc {
|
||||
struct device sc_dev;
|
||||
|
@ -141,16 +140,17 @@ struct wdc_softc {
|
|||
u_char sc_error; /* copy of error register */
|
||||
u_short sc_iobase; /* i/o port base */
|
||||
int sc_timeout; /* timeout counter */
|
||||
} wdc_softc[NWDC];
|
||||
|
||||
int wdcprobe(), wdcattach(), wdprobe(), wdattach(), wdintr();
|
||||
|
||||
struct isa_driver wdcdriver = {
|
||||
wdcprobe, wdcattach, "wdc",
|
||||
};
|
||||
|
||||
struct isa_driver wddriver = {
|
||||
wdprobe, wdattach, "wd",
|
||||
int wdcprobe(), wdprobe(), wdintr();
|
||||
void wdcattach(), wdattach();
|
||||
|
||||
struct cfdriver wdccd = {
|
||||
NULL, "wdc", wdcprobe, wdcattach, DV_DULL, sizeof(struct wd_softc)
|
||||
};
|
||||
|
||||
struct cfdriver wdcd = {
|
||||
NULL, "wd", wdprobe, wdattach, DV_DISK, sizeof(struct wd_softc)
|
||||
};
|
||||
|
||||
void wdfinish __P((struct wd_softc *, struct buf *));
|
||||
|
@ -176,22 +176,16 @@ int wdcwait __P((struct wdc_softc *, int));
|
|||
* Probe for controller.
|
||||
*/
|
||||
int
|
||||
wdcprobe(dev)
|
||||
struct isa_device *dev;
|
||||
wdcprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct wdc_softc *wdc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct wd_softc *wd;
|
||||
struct wdc_softc *wdc;
|
||||
u_short iobase;
|
||||
|
||||
if (dev->id_unit >= NWDC)
|
||||
return 0;
|
||||
wdc = &wdc_softc[dev->id_unit];
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(wdc->sc_dev.dv_xname, "%s%d", wdcdriver.name, dev->id_unit);
|
||||
wdc->sc_dev.dv_unit = dev->id_unit;
|
||||
|
||||
wdc->sc_iobase = iobase = dev->id_iobase;
|
||||
wdc->sc_iobase = iobase = ia->ia_iobase;
|
||||
|
||||
/* Check if we have registers that work. */
|
||||
outb(iobase+wd_error, 0x5a); /* Error register not writable. */
|
||||
|
@ -210,8 +204,8 @@ wdcprobe(dev)
|
|||
*/
|
||||
wd = (void *)malloc(sizeof(struct wd_softc), M_TEMP, M_NOWAIT);
|
||||
bzero(wd, sizeof(struct wd_softc));
|
||||
wd->sc_unit = 0;
|
||||
wd->sc_lunit = 0;
|
||||
wd->sc_drive = 0;
|
||||
wd->sc_dev.dv_unit = 0;
|
||||
wd->sc_dev.dv_parent = (void *)wdc;
|
||||
|
||||
/* Execute a controller only command. */
|
||||
|
@ -219,76 +213,89 @@ wdcprobe(dev)
|
|||
wait_for_unbusy(wdc) != 0)
|
||||
goto lose;
|
||||
|
||||
wdctimeout(wdc);
|
||||
|
||||
free(wd, M_TEMP);
|
||||
return 8;
|
||||
ia->ia_iosize = 8;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
|
||||
lose:
|
||||
free(wd, M_TEMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
wdcattach(dev)
|
||||
struct isa_device *dev;
|
||||
{
|
||||
struct wdc_attach_args {
|
||||
int wa_drive;
|
||||
};
|
||||
|
||||
int
|
||||
wdprint(aux, wdc)
|
||||
void *aux;
|
||||
char *wdc;
|
||||
{
|
||||
struct wdc_attach_args *wa = aux;
|
||||
|
||||
if (!wdc)
|
||||
printf(" drive %d", wa->wa_drive);
|
||||
return QUIET;
|
||||
}
|
||||
|
||||
void
|
||||
wdcattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct wdc_softc *wdc = (void *)self;
|
||||
struct wdc_attach_args wa;
|
||||
|
||||
wdctimeout(wdc);
|
||||
printf("\n");
|
||||
|
||||
for (wa.wa_drive = 0; wa.wa_drive < 2; wa.wa_drive++)
|
||||
(void)config_found(self, &wa, wdprint);
|
||||
}
|
||||
|
||||
int
|
||||
wdprobe(dev)
|
||||
struct isa_device *dev;
|
||||
wdprobe(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct wd_softc *wd = (void *)self;
|
||||
struct cfdata *cf = wd->sc_dev.dv_cfdata;
|
||||
struct wdc_attach_args *wa = aux;
|
||||
int drive = wa->wa_drive;
|
||||
#ifdef NEWCONFIG
|
||||
|
||||
#define cf_drive cf_loc[0]
|
||||
if (cf->cf_drive != -1 && cf->cf_drive != drive)
|
||||
return 0;
|
||||
#undef cf_drive
|
||||
#else
|
||||
struct isa_device *id = (void *)cf->cf_loc;
|
||||
|
||||
if (id->id_physid != -1 && id->id_physid != drive)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
wd->sc_drive = drive;
|
||||
|
||||
if (wdgetctlr(wd) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for the controller too. Attach each drive if possible.
|
||||
*/
|
||||
int
|
||||
wdattach(dev)
|
||||
struct isa_device *dev;
|
||||
void
|
||||
wdattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
int lunit;
|
||||
struct wd_softc *wd;
|
||||
struct wdc_softc *wdc;
|
||||
struct wd_softc *wd = (void *)self;
|
||||
int i, blank;
|
||||
|
||||
lunit = dev->id_unit;
|
||||
if (lunit == -1) {
|
||||
printf("%s: cannot support unit ?\n", wdc->sc_dev.dv_xname);
|
||||
return 0;
|
||||
}
|
||||
if (lunit >= NWD)
|
||||
return 0;
|
||||
|
||||
wdc = &wdc_softc[dev->id_parent->id_unit];
|
||||
|
||||
wd_softc[lunit] = wd =
|
||||
(void *)malloc(sizeof(struct wd_softc), M_TEMP, M_NOWAIT);
|
||||
bzero(wd, sizeof(struct wd_softc));
|
||||
wd->sc_unit = dev->id_physid;
|
||||
wd->sc_lunit = lunit;
|
||||
|
||||
/* XXX HACK */
|
||||
sprintf(wd->sc_dev.dv_xname, "%s%d", wddriver.name, dev->id_unit);
|
||||
wd->sc_dev.dv_unit = dev->id_unit;
|
||||
wd->sc_dev.dv_parent = (void *)wdc;
|
||||
|
||||
if (wdgetctlr(wd) != 0) {
|
||||
wd_softc[lunit] = NULL;
|
||||
free(wd, M_TEMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("%s at %s targ %d: ", wd->sc_dev.dv_xname, wdc->sc_dev.dv_xname,
|
||||
dev->id_physid);
|
||||
if (wd->sc_params.wdp_heads == 0)
|
||||
printf("(unknown size) <");
|
||||
printf(": (unknown size) <");
|
||||
else
|
||||
printf("%dMB %d cyl, %d head, %d sec <",
|
||||
printf(": %dMB %d cyl, %d head, %d sec <",
|
||||
wd->sc_label.d_ncylinders * wd->sc_label.d_secpercyl /
|
||||
(1048576 / DEV_BSIZE),
|
||||
wd->sc_label.d_ncylinders, wd->sc_label.d_ntracks,
|
||||
|
@ -307,8 +314,6 @@ wdattach(dev)
|
|||
blank = 1;
|
||||
}
|
||||
printf(">\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -328,9 +333,9 @@ wdstrategy(bp)
|
|||
int s;
|
||||
|
||||
/* Valid unit, controller, and request? */
|
||||
if (lunit >= NWD || bp->b_blkno < 0 ||
|
||||
if (lunit >= wdcd.cd_ndevs || bp->b_blkno < 0 ||
|
||||
howmany(bp->b_bcount, DEV_BSIZE) >= (1 << NBBY) ||
|
||||
(wd = wd_softc[lunit]) == 0) {
|
||||
(wd = wdcd.cd_devs[lunit]) == 0) {
|
||||
bp->b_error = EINVAL;
|
||||
bp->b_flags |= B_ERROR;
|
||||
goto done;
|
||||
|
@ -431,7 +436,7 @@ wdfinish(wd, bp)
|
|||
struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
|
||||
|
||||
#ifdef INSTRUMENT
|
||||
dk_busy &= ~(1 << wd->sc_unit);
|
||||
dk_busy &= ~(1 << wd->sc_drive);
|
||||
#endif
|
||||
wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR);
|
||||
wdc->sc_q.b_errcnt = 0;
|
||||
|
@ -496,7 +501,7 @@ loop:
|
|||
|
||||
/* Obtain controller and drive information */
|
||||
lunit = WDUNIT(bp->b_dev);
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
|
||||
if (wdc->sc_q.b_errcnt >= WDIORETRIES) {
|
||||
wderror(wd, bp, "hard error");
|
||||
|
@ -621,8 +626,8 @@ loop:
|
|||
|
||||
#ifdef INSTRUMENT
|
||||
if (wd->sc_skip == 0) {
|
||||
dk_busy |= 1 << wd->sc_lunit;
|
||||
dk_wds[wd->sc_lunit] += bp->b_bcount >> 6;
|
||||
dk_busy |= 1 << wd->sc_dev.dv_unit;
|
||||
dk_wds[wd->sc_dev.dv_unit] += bp->b_bcount >> 6;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -631,8 +636,8 @@ loop:
|
|||
int command, count;
|
||||
|
||||
#ifdef INSTRUMENT
|
||||
++dk_seek[wd->sc_lunit];
|
||||
++dk_xfer[wd->sc_lunit];
|
||||
++dk_seek[wd->sc_dev.dv_unit];
|
||||
++dk_xfer[wd->sc_dev.dv_unit];
|
||||
#endif
|
||||
|
||||
#ifdef B_FORMAT
|
||||
|
@ -694,7 +699,7 @@ int
|
|||
wdintr(ctrlr)
|
||||
int ctrlr;
|
||||
{
|
||||
struct wdc_softc *wdc = &wdc_softc[ctrlr];
|
||||
struct wdc_softc *wdc = wdccd.cd_devs[ctrlr];
|
||||
struct wd_softc *wd;
|
||||
struct buf *bp;
|
||||
|
||||
|
@ -707,7 +712,7 @@ wdintr(ctrlr)
|
|||
}
|
||||
|
||||
bp = wdc->sc_q.b_forw->b_actf;
|
||||
wd = wd_softc[WDUNIT(bp->b_dev)];
|
||||
wd = wdcd.cd_devs[WDUNIT(bp->b_dev)];
|
||||
wdc->sc_timeout = 0;
|
||||
|
||||
#ifdef WDDEBUG
|
||||
|
@ -816,9 +821,9 @@ wdopen(dev, flag, fmt, p)
|
|||
char *msg;
|
||||
|
||||
lunit = WDUNIT(dev);
|
||||
if (lunit >= NWD)
|
||||
if (lunit >= wdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
if (wd == 0)
|
||||
return ENXIO;
|
||||
|
||||
|
@ -996,7 +1001,7 @@ wdcommand(wd, cylin, head, sector, count, cmd)
|
|||
|
||||
/* Select drive. */
|
||||
iobase = wdc->sc_iobase;
|
||||
outb(iobase+wd_sdh, WDSD_IBM | (wd->sc_unit << 4) | head);
|
||||
outb(iobase+wd_sdh, WDSD_IBM | (wd->sc_drive << 4) | head);
|
||||
if (cmd == WDCC_DIAGNOSE || cmd == WDCC_IDC)
|
||||
stat = wait_for_unbusy(wdc);
|
||||
else
|
||||
|
@ -1027,7 +1032,7 @@ wdsetctlr(wd)
|
|||
struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
|
||||
|
||||
#ifdef WDDEBUG
|
||||
printf("wd(%d,%d) C%dH%dS%d\n", wd->sc_ctrlr, wd->sc_unit,
|
||||
printf("wd(%d,%d) C%dH%dS%d\n", wd->sc_ctrlr, wd->sc_drive,
|
||||
wd->sc_label.d_ncylinders, wd->sc_label.d_ntracks,
|
||||
wd->sc_label.d_nsectors);
|
||||
#endif
|
||||
|
@ -1119,7 +1124,7 @@ wdclose(dev, flag, fmt)
|
|||
int flag;
|
||||
int fmt;
|
||||
{
|
||||
struct wd_softc *wd = wd_softc[WDUNIT(dev)];
|
||||
struct wd_softc *wd = wdcd.cd_devs[WDUNIT(dev)];
|
||||
int part = WDPART(dev), mask = 1 << part;
|
||||
|
||||
switch (fmt) {
|
||||
|
@ -1144,7 +1149,7 @@ wdioctl(dev, cmd, addr, flag, p)
|
|||
struct proc *p;
|
||||
{
|
||||
int lunit = WDUNIT(dev);
|
||||
struct wd_softc *wd = wd_softc[lunit];
|
||||
struct wd_softc *wd = wdcd.cd_devs[lunit];
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -1269,9 +1274,9 @@ wdsize(dev)
|
|||
int lunit = WDUNIT(dev), part = WDPART(dev);
|
||||
struct wd_softc *wd;
|
||||
|
||||
if (lunit >= NWD)
|
||||
if (lunit >= wdcd.cd_ndevs)
|
||||
return -1;
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
if (wd == 0)
|
||||
return -1;
|
||||
|
||||
|
@ -1319,9 +1324,9 @@ wddump(dev)
|
|||
|
||||
lunit = WDUNIT(dev);
|
||||
/* Check for acceptable drive number. */
|
||||
if (lunit >= NWD)
|
||||
if (lunit >= wdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
wd = wd_softc[lunit];
|
||||
wd = wdcd.cd_devs[lunit];
|
||||
/* Was it ever initialized? */
|
||||
if (wd == 0 || wd->sc_state < OPEN || wd->sc_flags & WDF_WRITEPROT)
|
||||
return ENXIO;
|
||||
|
@ -1511,8 +1516,8 @@ wdcunwedge(wdc)
|
|||
(void) wdcreset(wdc);
|
||||
|
||||
/* Schedule recalibrate for all drives on this controller. */
|
||||
for (lunit = 0; lunit < NWD; lunit++) {
|
||||
struct wd_softc *wd = wd_softc[lunit];
|
||||
for (lunit = 0; lunit < wdcd.cd_ndevs; lunit++) {
|
||||
struct wd_softc *wd = wdcd.cd_devs[lunit];
|
||||
if (!wd || (void *)wd->sc_dev.dv_parent != wdc)
|
||||
continue;
|
||||
if (wd->sc_state > RECAL)
|
||||
|
@ -1582,5 +1587,3 @@ wderror(dev, bp, msg)
|
|||
printf("%s: %s: status %b error %b\n", wdc->sc_dev.dv_xname,
|
||||
msg, wdc->sc_status, WDCS_BITS, wdc->sc_error, WDERR_BITS);
|
||||
}
|
||||
|
||||
#endif /* NWDC > 0 */
|
||||
|
|
Loading…
Reference in New Issue