Updates for new autoconfig.

This commit is contained in:
mycroft 1994-03-29 04:35:37 +00:00
parent 5eb99ad76e
commit 592ec61b17
35 changed files with 2187 additions and 2129 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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++;

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
/*

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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++;

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 */