PR/6274: John Ruschmeyer: Add support for the ncr53c80 driver on the i386.
This commit is contained in:
parent
94b2d42842
commit
906db1e920
|
@ -0,0 +1,186 @@
|
|||
NCR 53C80/53C400 driver
|
||||
|
||||
BACKGROUND
|
||||
----------
|
||||
The NCR 53C80 SCSI Bus Controller (SBC) is an early single-chip solution
|
||||
which formed the basis of many early SCSI host adapters for both the
|
||||
i386 and m68k platforms. The NCR 53C400 is a slightly more advanced
|
||||
chip which retains backward compatability with the 53C80.
|
||||
|
||||
On the PC, the NCR 53C80 was most commonly used to implement simple, cheap
|
||||
SCSI host adapters that were bundled with tape and CD-ROM drives. Since
|
||||
these controllers were not bus-mastering (and in some cases were not even
|
||||
interrupt-driven), they (like IDE adapters) required the CPU to perform
|
||||
much of the actual processing. These days, these controllers are cheap
|
||||
and plentiful since many are not supported by Windows 95.
|
||||
|
||||
Similarly, NetBSD, although it has had an MI 53C80 driver (used by the
|
||||
Sun3 and Mac68k ports) for some time, has not had a i386 driver.
|
||||
|
||||
Until now, that is...
|
||||
|
||||
OVERVIEW
|
||||
--------
|
||||
The NCR 53C80/53C400 driver (the 'nca' device) consists of two pieces:
|
||||
|
||||
1) Patches for the 53C80 MI driver to make it use bus_space()
|
||||
functions. (This requires an optional define. By default,
|
||||
the driver will compile in "legacy" memory-mapped mode.
|
||||
|
||||
2) A machine-dependent driver (nca) containing probe and
|
||||
attachment routines.
|
||||
|
||||
This driver has bene tested with the following adapters:
|
||||
|
||||
NCS-250 (Chinon) 53C80, port-mapped, polled-mode
|
||||
(This is used in my primary development
|
||||
box to drive an external Zip drive.)
|
||||
Sumo SCSI-AT 53C80, port-mapped, interrupt driven
|
||||
(Note: This is an odd card in that its
|
||||
own firmware seems to have trouble detecting
|
||||
attached drives. Under NetBSD, however,
|
||||
it operates with no problems.)
|
||||
Trantor T-160 53C400, port-mapped, interrupt driven
|
||||
This card was often bundled with NEC
|
||||
CD-ROM drives. (My standalone test box
|
||||
is using this as its primary adapter.)
|
||||
DTC 3150V 53C400, memory-mapped, interrupt driven
|
||||
This a simple card designed to drive
|
||||
a CD-ROM.
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
To setup the nca driver, the configuration file must contain the following:
|
||||
|
||||
options NCR5380_USE_BUS_SPACE
|
||||
|
||||
This line is required to add bus_space() compatability to the MI driver.
|
||||
|
||||
Next you need to add one or more configuration lines for the nca devices:
|
||||
|
||||
nca0 at isa? port 0x360 irq 15
|
||||
nca1 at isa? iomem 0xd8000 irq 5
|
||||
|
||||
The first is for a port-mapped controller at 0x360, IRQ 15. The second line
|
||||
is for a memory-mapped controller (Trantor T128 or equivalent) at
|
||||
0xd800-0xdff, IRQ 5.
|
||||
|
||||
You can also set up the driver in "polled" mode (i.e., no interrupts) by
|
||||
leaving off the "irq" portion of the line:
|
||||
|
||||
nca0 at isa? port 0x360
|
||||
nca1 at isa? iomem 0xd8000
|
||||
|
||||
Lastly, you need to add a scsibus attachment line for the nca device:
|
||||
|
||||
scsibus* at nca?
|
||||
|
||||
The following is the probe output from my test system:
|
||||
|
||||
Copyright (c) 1996, 1997, 1998
|
||||
The NetBSD Foundation, Inc. All rights reserved.
|
||||
Copyright (c) 1982, 1986, 1989, 1991, 1993
|
||||
The Regents of the University of California. All rights reserved.
|
||||
|
||||
NetBSD 1.3.2 (GENERIC) #2: Sun Oct 4 17:11:43 EDT 1998
|
||||
root@hefalump:/usr/src/sys/arch/i386/compile/GENERIC
|
||||
cpu0: Intel 486DX (486-class)
|
||||
real mem = 7995392
|
||||
avail mem = 5349376
|
||||
using 123 buffers containing 503808 bytes of memory
|
||||
mainbus0 (root)
|
||||
isa0 at mainbus0
|
||||
com1 at isa0 port 0x2f8-0x2ff irq 3: ns8250 or ns16450, no fifo
|
||||
com2 at isa0 port 0x3e8-0x3ef irq 5: ns8250 or ns16450, no fifo
|
||||
lpt0 at isa0 port 0x378-0x37b irq 7
|
||||
nca0 at isa0 port 0x360-0x36f irq 15
|
||||
nca0: NCR 53C400 detected
|
||||
scsibus0 at nca0: 8 targets
|
||||
sd0 at scsibus0 targ 0 lun 0: <HP, C2235, 0B11> SCSI2 0/direct fixed
|
||||
sd0: 402MB, 1574 cyl, 9 head, 58 sec, 512 bytes/sect x 825012 sectors
|
||||
cd0 at scsibus0 targ 6 lun 0: <CHINON, CD-ROM CDS-535, Q20> SCSI2 5/cdrom removable
|
||||
nca1 at isa0 iomem 0xdb878-0xdb887 irq 5
|
||||
nca1: NCR 53C400 detected
|
||||
scsibus1 at nca1: 8 targets
|
||||
sd1 at scsibus1 targ 5 lun 0: <IOMEGA, ZIP 100, J.02> SCSI2 0/direct removable
|
||||
sd1: 96MB, 96 cyl, 64 head, 32 sec, 512 bytes/sect x 196608 sectors
|
||||
npx0 at isa0 port 0xf0-0xff: using exception 16
|
||||
pc0 at isa0 port 0x60-0x6f irq 1: color
|
||||
pc0: console
|
||||
fdc0 at isa0 port 0x3f0-0x3f7 irq 6 drq 2
|
||||
fd0 at fdc0 drive 0: 1.44MB, 80 cyl, 2 head, 18 sec
|
||||
biomask 8060 netmask 8460 ttymask 84e2
|
||||
boot device: sd0
|
||||
root on sd0a dumps on sd0b
|
||||
root file system type: ffs
|
||||
|
||||
In this output, nca0 is a Trantor T-160 and nca1 is a DTC 3150V. Both happen
|
||||
to be 53C400-based controllers.
|
||||
|
||||
LIMITATIONS
|
||||
-----------
|
||||
As of this writing, the nca driver has two known limitations:
|
||||
|
||||
1) No DMA or pseudo-DMA support
|
||||
|
||||
This is unfortunate, but may be remedied in a later release. I would welcome
|
||||
any help by someone more familiar with DMA, particularly in relation to
|
||||
bus_space().
|
||||
|
||||
As it is, however, performance of the nca driver is acceptable, though some
|
||||
of that may depend on one's definition of "acceptable". Remember that these
|
||||
were not high speed controller under the best conditions, so much of it is
|
||||
really the nature of the beast. It should be adequate for tapes, CD-ROMS,
|
||||
and low-usage disk devices (e.g., Zip drives). If you want to drive a CD-R
|
||||
drive, then invest in an Adaptec 154X or a PCI controller.
|
||||
|
||||
2) No support for the SCSI port of the Pro AudioStudio 16.
|
||||
|
||||
This is also unfortunate and may not be able to be remedied withing the
|
||||
current framework of the bus_space() functions and the nca driver.
|
||||
|
||||
The problem is this: In most adapters, the eight 53C80 registers are mapped
|
||||
to eight sequential locations, either ports or memory addresses. On the
|
||||
PAS-16, however, the registers are mapped to two sets of ports- four
|
||||
sequential ports at the base address and four sequential ports located
|
||||
0x2000 higher. As I currently understand it, this is not supportable by
|
||||
the current bus_space() implementation nor is it possible for the driver
|
||||
to allocate a second bus_space_tag and _handle itself to accomodate the
|
||||
second set of ports. Without either, it is very difficult to imagine how
|
||||
a portable linkage to the MI driver could be made.
|
||||
|
||||
Again, I welcome suggestions.
|
||||
|
||||
HISTORY
|
||||
-------
|
||||
An nca driver first appeared in FreeBSD.
|
||||
|
||||
This particular one borrows a little code from it and some from the i386
|
||||
'esp' and sun3 'si' drivers. It, like many things in the free unix world,
|
||||
was written because it solved a problem- mine! In my case, it was a need
|
||||
of a SCSI card and a lack of IRQs. The good news was that I had one
|
||||
(NCS-250); the bad news was that it was not supported under NetBSD. The
|
||||
rest is history.
|
||||
|
||||
DISCLAIMER
|
||||
----------
|
||||
Like most things, you should take this code with a grain of salt. I have
|
||||
tried to test it sufficiently, but it is always possible that it is not
|
||||
compatible with some aspect of your system. If you end up suffering
|
||||
massive data loss and destruction, you have my sympathies, but I do not
|
||||
and will not allow myself to be held responsible.
|
||||
|
||||
CREDITS
|
||||
-------
|
||||
My thanks to Jason Thorpe and the rest of the NetBSD team for making it
|
||||
so easy to write this driver. My thanks also to the authors of the
|
||||
FreeBSD nca driver for inspiration and 53C400 support.
|
||||
|
||||
In the end, I hope that someone else can find this driver as useful as I
|
||||
have. If so, please drop me a line at jruschme@exit109.com and let me
|
||||
know about it.
|
||||
|
||||
Share and enjoy
|
||||
|
||||
John Ruschmeyer (jruschme@exit109.com)
|
||||
11 October 1998
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ncr5380sbc.c,v 1.27 1998/09/16 05:36:35 scottr Exp $ */
|
||||
/* $NetBSD: ncr5380sbc.c,v 1.28 1998/10/25 17:26:41 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 David Jones, Gordon W. Ross
|
||||
|
@ -64,6 +64,10 @@
|
|||
* Michael L. Hitch (amiga drivers: sci.c)
|
||||
* Leo Weppelman (atari driver: ncr5380.c)
|
||||
* There are others too. Thanks, everyone.
|
||||
*
|
||||
* Transliteration to bus_space() performed 9/17/98 by
|
||||
* John Ruschmeyer (jruschme@exit109.com) for i386 'nca' driver.
|
||||
* Thank you all.
|
||||
*/
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
@ -186,7 +190,7 @@ static __inline int ncr5380_wait_req(sc)
|
|||
{
|
||||
register int timo = ncr5380_wait_req_timo;
|
||||
for (;;) {
|
||||
if (*sc->sci_bus_csr & SCI_BUS_REQ) {
|
||||
if (NCR5380_READ(sci_bus_csr) & SCI_BUS_REQ) {
|
||||
timo = 0; /* return 0 */
|
||||
break;
|
||||
}
|
||||
|
@ -203,7 +207,7 @@ static __inline int ncr5380_wait_not_req(sc)
|
|||
{
|
||||
register int timo = ncr5380_wait_nrq_timo;
|
||||
for (;;) {
|
||||
if ((*sc->sci_bus_csr & SCI_BUS_REQ) == 0) {
|
||||
if ((NCR5380_READ(sci_bus_csr) & SCI_BUS_REQ) == 0) {
|
||||
timo = 0; /* return 0 */
|
||||
break;
|
||||
}
|
||||
|
@ -223,8 +227,8 @@ ncr_sched_msgout(sc, msg_code)
|
|||
/* First time, raise ATN line. */
|
||||
if (sc->sc_msgpriq == 0) {
|
||||
register u_char icmd;
|
||||
icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
|
||||
*sc->sci_icmd = icmd | SCI_ICMD_ATN;
|
||||
icmd = NCR5380_READ(sci_icmd) & SCI_ICMD_RMASK;
|
||||
NCR5380_WRITE(sci_icmd,icmd|SCI_ICMD_ATN);
|
||||
delay(2);
|
||||
}
|
||||
sc->sc_msgpriq |= msg_code;
|
||||
|
@ -241,10 +245,10 @@ ncr5380_pio_out(sc, phase, count, data)
|
|||
register int resid;
|
||||
register int error;
|
||||
|
||||
icmd = *(sc->sci_icmd) & SCI_ICMD_RMASK;
|
||||
icmd = NCR5380_READ(sci_icmd) & SCI_ICMD_RMASK;
|
||||
|
||||
icmd |= SCI_ICMD_DATA;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
resid = count;
|
||||
while (resid > 0) {
|
||||
|
@ -256,25 +260,25 @@ ncr5380_pio_out(sc, phase, count, data)
|
|||
NCR_TRACE("pio_out: no REQ, resid=%d\n", resid);
|
||||
break;
|
||||
}
|
||||
if (SCI_BUS_PHASE(*sc->sci_bus_csr) != phase)
|
||||
if (SCI_BUS_PHASE(NCR5380_READ(sci_bus_csr)) != phase)
|
||||
break;
|
||||
|
||||
/* Put the data on the bus. */
|
||||
if (data)
|
||||
*sc->sci_odata = *data++;
|
||||
NCR5380_WRITE(sci_odata,*data++);
|
||||
else
|
||||
*sc->sci_odata = 0;
|
||||
NCR5380_WRITE(sci_odata,0);
|
||||
|
||||
/* Tell the target it's there. */
|
||||
icmd |= SCI_ICMD_ACK;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
/* Wait for target to get it. */
|
||||
error = ncr5380_wait_not_req(sc);
|
||||
|
||||
/* OK, it's got it (or we gave up waiting). */
|
||||
icmd &= ~SCI_ICMD_ACK;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
if (error) {
|
||||
NCR_TRACE("pio_out: stuck REQ, resid=%d\n", resid);
|
||||
|
@ -286,7 +290,7 @@ ncr5380_pio_out(sc, phase, count, data)
|
|||
|
||||
/* Stop driving the data bus. */
|
||||
icmd &= ~SCI_ICMD_DATA;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
return (count - resid);
|
||||
}
|
||||
|
@ -302,7 +306,7 @@ ncr5380_pio_in(sc, phase, count, data)
|
|||
register int resid;
|
||||
register int error;
|
||||
|
||||
icmd = *(sc->sci_icmd) & SCI_ICMD_RMASK;
|
||||
icmd = NCR5380_READ(sci_icmd) & SCI_ICMD_RMASK;
|
||||
|
||||
resid = count;
|
||||
while (resid > 0) {
|
||||
|
@ -315,25 +319,25 @@ ncr5380_pio_in(sc, phase, count, data)
|
|||
break;
|
||||
}
|
||||
/* A phase change is not valid until AFTER REQ rises! */
|
||||
if (SCI_BUS_PHASE(*sc->sci_bus_csr) != phase)
|
||||
if (SCI_BUS_PHASE(NCR5380_READ(sci_bus_csr)) != phase)
|
||||
break;
|
||||
|
||||
/* Read the data bus. */
|
||||
if (data)
|
||||
*data++ = *sc->sci_data;
|
||||
*data++ = NCR5380_READ(sci_data);
|
||||
else
|
||||
(void) *sc->sci_data;
|
||||
(void) NCR5380_READ(sci_data);
|
||||
|
||||
/* Tell target we got it. */
|
||||
icmd |= SCI_ICMD_ACK;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
/* Wait for target to drop REQ... */
|
||||
error = ncr5380_wait_not_req(sc);
|
||||
|
||||
/* OK, we can drop ACK. */
|
||||
icmd &= ~SCI_ICMD_ACK;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
if (error) {
|
||||
NCR_TRACE("pio_in: stuck REQ, resid=%d\n", resid);
|
||||
|
@ -369,14 +373,14 @@ ncr5380_init(sc)
|
|||
sc->sc_prevphase = PHASE_INVALID;
|
||||
sc->sc_state = NCR_IDLE;
|
||||
|
||||
*sc->sci_tcmd = PHASE_INVALID;
|
||||
*sc->sci_icmd = 0;
|
||||
*sc->sci_mode = 0;
|
||||
*sc->sci_sel_enb = 0;
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_INVALID);
|
||||
NCR5380_WRITE(sci_icmd,0);
|
||||
NCR5380_WRITE(sci_mode,0);
|
||||
NCR5380_WRITE(sci_sel_enb,0);
|
||||
SCI_CLR_INTR(sc);
|
||||
|
||||
/* XXX: Enable reselect interrupts... */
|
||||
*sc->sci_sel_enb = 0x80;
|
||||
NCR5380_WRITE(sci_sel_enb,0x80);
|
||||
|
||||
/* Another hack (Er.. hook!) for the sun3 si: */
|
||||
if (sc->sc_intr_on) {
|
||||
|
@ -394,12 +398,12 @@ ncr5380_reset_scsibus(sc)
|
|||
NCR_TRACE("reset_scsibus, cur=0x%x\n",
|
||||
(long) sc->sc_current);
|
||||
|
||||
*sc->sci_icmd = SCI_ICMD_RST;
|
||||
NCR5380_WRITE(sci_icmd,SCI_ICMD_RST);
|
||||
delay(500);
|
||||
*sc->sci_icmd = 0;
|
||||
NCR5380_WRITE(sci_icmd,0);
|
||||
|
||||
*sc->sci_mode = 0;
|
||||
*sc->sci_tcmd = PHASE_INVALID;
|
||||
NCR5380_WRITE(sci_mode,0);
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_INVALID);
|
||||
|
||||
SCI_CLR_INTR(sc);
|
||||
/* XXX - Need long delay here! */
|
||||
|
@ -1084,7 +1088,7 @@ ncr5380_reselect(sc)
|
|||
* First, check the select line.
|
||||
* (That has to be set first.)
|
||||
*/
|
||||
bus = *(sc->sci_bus_csr);
|
||||
bus = NCR5380_READ(sci_bus_csr);
|
||||
if ((bus & SCI_BUS_SEL) == 0) {
|
||||
/* Not a selection or reselection. */
|
||||
return;
|
||||
|
@ -1111,7 +1115,7 @@ ncr5380_reselect(sc)
|
|||
return;
|
||||
}
|
||||
delay(2);
|
||||
bus = *(sc->sci_bus_csr);
|
||||
bus = NCR5380_READ(sci_bus_csr);
|
||||
/* If SEL went away, forget it. */
|
||||
if ((bus & SCI_BUS_SEL) == 0)
|
||||
return;
|
||||
|
@ -1125,7 +1129,7 @@ ncr5380_reselect(sc)
|
|||
* "bus settle delay" before we sample the data bus
|
||||
*/
|
||||
delay(2);
|
||||
data = *(sc->sci_data) & 0xFF;
|
||||
data = NCR5380_READ(sci_data) & 0xFF;
|
||||
/* Parity check is implicit in data validation below. */
|
||||
|
||||
/*
|
||||
|
@ -1159,12 +1163,12 @@ ncr5380_reselect(sc)
|
|||
NCR_TRACE("reselect: target=0x%x\n", target);
|
||||
|
||||
/* Raise BSY to acknowledge target reselection. */
|
||||
*(sc->sci_icmd) = SCI_ICMD_BSY;
|
||||
NCR5380_WRITE(sci_icmd,SCI_ICMD_BSY);
|
||||
|
||||
/* Wait for target to drop SEL. */
|
||||
timo = ncr5380_wait_nrq_timo;
|
||||
for (;;) {
|
||||
bus = *(sc->sci_bus_csr);
|
||||
bus = NCR5380_READ(sci_bus_csr);
|
||||
if ((bus & SCI_BUS_SEL) == 0)
|
||||
break; /* success */
|
||||
if (--timo <= 0) {
|
||||
|
@ -1178,8 +1182,8 @@ ncr5380_reselect(sc)
|
|||
}
|
||||
|
||||
/* Now we drop BSY, and we are connected. */
|
||||
*(sc->sci_icmd) = 0;
|
||||
*sc->sci_sel_enb = 0;
|
||||
NCR5380_WRITE(sci_icmd,0);
|
||||
NCR5380_WRITE(sci_sel_enb,0);
|
||||
SCI_CLR_INTR(sc);
|
||||
|
||||
/*
|
||||
|
@ -1195,7 +1199,7 @@ ncr5380_reselect(sc)
|
|||
/* Try to send an ABORT message. */
|
||||
goto abort;
|
||||
}
|
||||
phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
|
||||
phase = SCI_BUS_PHASE(NCR5380_READ(sci_bus_csr));
|
||||
if (phase != PHASE_MSG_IN) {
|
||||
printf("%s: reselect, phase=%d\n",
|
||||
sc->sc_dev.dv_xname, phase);
|
||||
|
@ -1203,10 +1207,10 @@ ncr5380_reselect(sc)
|
|||
}
|
||||
|
||||
/* Ack. the change to PHASE_MSG_IN */
|
||||
*(sc->sci_tcmd) = PHASE_MSG_IN;
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_MSG_IN);
|
||||
|
||||
/* Peek at the message byte without consuming it! */
|
||||
msg = *(sc->sci_data);
|
||||
msg = NCR5380_READ(sci_data);
|
||||
if ((msg & 0x80) == 0) {
|
||||
printf("%s: reselect, not identify, msg=%d\n",
|
||||
sc->sc_dev.dv_xname, msg);
|
||||
|
@ -1234,9 +1238,9 @@ ncr5380_reselect(sc)
|
|||
/* XXX: Restore the normal mode register. */
|
||||
/* If this target's bit is set, do NOT check parity. */
|
||||
if (sc->sc_parity_disable & target_mask)
|
||||
*sc->sci_mode = (SCI_MODE_MONBSY);
|
||||
NCR5380_WRITE(sci_mode,SCI_MODE_MONBSY);
|
||||
else
|
||||
*sc->sci_mode = (SCI_MODE_MONBSY | SCI_MODE_PAR_CHK);
|
||||
NCR5380_WRITE(sci_mode,(SCI_MODE_MONBSY | SCI_MODE_PAR_CHK));
|
||||
|
||||
/*
|
||||
* Another hack for the Sun3 "si", which needs
|
||||
|
@ -1265,7 +1269,7 @@ abort:
|
|||
|
||||
/* Raise ATN, delay, raise ACK... */
|
||||
icmd = SCI_ICMD_ATN;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
delay(2);
|
||||
|
||||
/* Now consume the IDENTIFY message. */
|
||||
|
@ -1276,10 +1280,10 @@ abort:
|
|||
sc->sc_msgpriq = SEND_ABORT;
|
||||
ncr5380_msg_out(sc);
|
||||
|
||||
*(sc->sci_tcmd) = PHASE_INVALID;
|
||||
*sc->sci_sel_enb = 0;
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_INVALID);
|
||||
NCR5380_WRITE(sci_sel_enb,0);
|
||||
SCI_CLR_INTR(sc);
|
||||
*sc->sci_sel_enb = 0x80;
|
||||
NCR5380_WRITE(sci_sel_enb,0x80);
|
||||
|
||||
sc->sc_state &= ~NCR_ABORTING;
|
||||
}
|
||||
|
@ -1315,9 +1319,10 @@ ncr5380_select(sc, sr)
|
|||
* Set phase bits to 0, otherwise the 5380 won't drive the bus during
|
||||
* selection.
|
||||
*/
|
||||
*sc->sci_tcmd = PHASE_DATA_OUT;
|
||||
*sc->sci_icmd = icmd = 0;
|
||||
*sc->sci_mode = 0;
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_DATA_OUT);
|
||||
NCR5380_WRITE(sci_icmd,0);
|
||||
icmd = 0;
|
||||
NCR5380_WRITE(sci_mode,0);
|
||||
|
||||
/*
|
||||
* Arbitrate for the bus. The 5380 takes care of the
|
||||
|
@ -1338,14 +1343,14 @@ ncr5380_select(sc, sr)
|
|||
*/
|
||||
s = splimp(); /* XXX: Begin time-critical section */
|
||||
|
||||
*(sc->sci_odata) = 0x80; /* OUR_ID */
|
||||
*(sc->sci_mode) = SCI_MODE_ARB;
|
||||
NCR5380_WRITE(sci_odata,0x80); /* OUR_ID */
|
||||
NCR5380_WRITE(sci_mode,SCI_MODE_ARB);
|
||||
|
||||
#define WAIT_AIP_USEC 20 /* pleanty of time */
|
||||
/* Wait for the AIP bit to turn on. */
|
||||
timo = WAIT_AIP_USEC;
|
||||
for (;;) {
|
||||
if (*(sc->sci_icmd) & SCI_ICMD_AIP)
|
||||
if (NCR5380_READ(sci_icmd) & SCI_ICMD_AIP)
|
||||
break;
|
||||
if (timo <= 0) {
|
||||
/*
|
||||
|
@ -1366,7 +1371,7 @@ ncr5380_select(sc, sr)
|
|||
delay(3);
|
||||
|
||||
/* Check for ICMD_LST */
|
||||
if (*(sc->sci_icmd) & SCI_ICMD_LST) {
|
||||
if (NCR5380_READ(sci_icmd) & SCI_ICMD_LST) {
|
||||
/* Some other target asserted SEL. */
|
||||
NCR_TRACE("select: lost one, rc=%d\n", XS_BUSY);
|
||||
goto lost_arb;
|
||||
|
@ -1383,7 +1388,7 @@ ncr5380_select(sc, sr)
|
|||
* BSY directly so we can turn off ARB mode.
|
||||
*/
|
||||
icmd = (SCI_ICMD_BSY | SCI_ICMD_SEL);
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
/*
|
||||
* "The SCSI device that wins arbitration shall wait
|
||||
|
@ -1399,13 +1404,13 @@ ncr5380_select(sc, sr)
|
|||
* there can be a higher selection ID than ours.
|
||||
* Keep this code for reference anyway...
|
||||
*/
|
||||
if (*(sc->sci_icmd) & SCI_ICMD_LST) {
|
||||
if (NCR5380_READ(sci_icmd) & SCI_ICMD_LST) {
|
||||
/* Some other target asserted SEL. */
|
||||
NCR_TRACE("select: lost two, rc=%d\n", XS_BUSY);
|
||||
|
||||
lost_arb:
|
||||
*sc->sci_icmd = 0;
|
||||
*sc->sci_mode = 0;
|
||||
NCR5380_WRITE(sci_icmd,0);
|
||||
NCR5380_WRITE(sci_mode,0);
|
||||
|
||||
splx(s); /* XXX: End of time-critical section. */
|
||||
|
||||
|
@ -1418,8 +1423,8 @@ ncr5380_select(sc, sr)
|
|||
}
|
||||
|
||||
/* Leave ARB mode Now that we drive BSY+SEL */
|
||||
*sc->sci_mode = 0;
|
||||
*sc->sci_sel_enb = 0;
|
||||
NCR5380_WRITE(sci_mode,0);
|
||||
NCR5380_WRITE(sci_sel_enb,0);
|
||||
|
||||
splx(s); /* XXX: End of time-critical section. */
|
||||
|
||||
|
@ -1431,14 +1436,14 @@ ncr5380_select(sc, sr)
|
|||
*/
|
||||
target_mask = (1 << sr->sr_target);
|
||||
data = 0x80 | target_mask;
|
||||
*(sc->sci_odata) = data;
|
||||
NCR5380_WRITE(sci_odata,data);
|
||||
icmd |= (SCI_ICMD_DATA | SCI_ICMD_ATN);
|
||||
*(sc->sci_icmd) = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
delay(2); /* two deskew delays. */
|
||||
|
||||
/* De-assert BSY (targets sample the data now). */
|
||||
icmd &= ~SCI_ICMD_BSY;
|
||||
*(sc->sci_icmd) = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
delay(3); /* Bus settle delay. */
|
||||
|
||||
/*
|
||||
|
@ -1446,7 +1451,7 @@ ncr5380_select(sc, sr)
|
|||
* SCSI spec. says wait for 250 mS.
|
||||
*/
|
||||
for (timo = 25000;;) {
|
||||
if (*sc->sci_bus_csr & SCI_BUS_BSY)
|
||||
if (NCR5380_READ(sci_bus_csr) & SCI_BUS_BSY)
|
||||
goto success;
|
||||
if (--timo <= 0)
|
||||
break;
|
||||
|
@ -1462,16 +1467,16 @@ ncr5380_select(sc, sr)
|
|||
* otherwise we release the bus.
|
||||
*/
|
||||
icmd &= ~SCI_ICMD_DATA;
|
||||
*(sc->sci_icmd) = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
delay(201);
|
||||
if ((*sc->sci_bus_csr & SCI_BUS_BSY) == 0) {
|
||||
if ((NCR5380_READ(sci_bus_csr) & SCI_BUS_BSY) == 0) {
|
||||
/* Really no device on bus */
|
||||
*sc->sci_tcmd = PHASE_INVALID;
|
||||
*sc->sci_icmd = 0;
|
||||
*sc->sci_mode = 0;
|
||||
*sc->sci_sel_enb = 0;
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_INVALID);
|
||||
NCR5380_WRITE(sci_icmd,0);
|
||||
NCR5380_WRITE(sci_mode,0);
|
||||
NCR5380_WRITE(sci_sel_enb,0);
|
||||
SCI_CLR_INTR(sc);
|
||||
*sc->sci_sel_enb = 0x80;
|
||||
NCR5380_WRITE(sci_sel_enb,0x80);
|
||||
NCR_TRACE("select: device down, rc=%d\n", XS_SELTIMEOUT);
|
||||
return XS_SELTIMEOUT;
|
||||
}
|
||||
|
@ -1483,13 +1488,13 @@ success:
|
|||
* Configure the ncr5380 to monitor BSY, parity.
|
||||
*/
|
||||
icmd &= ~(SCI_ICMD_DATA | SCI_ICMD_SEL);
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
/* If this target's bit is set, do NOT check parity. */
|
||||
if (sc->sc_parity_disable & target_mask)
|
||||
*sc->sci_mode = (SCI_MODE_MONBSY);
|
||||
NCR5380_WRITE(sci_mode,SCI_MODE_MONBSY);
|
||||
else
|
||||
*sc->sci_mode = (SCI_MODE_MONBSY | SCI_MODE_PAR_CHK);
|
||||
NCR5380_WRITE(sci_mode,(SCI_MODE_MONBSY | SCI_MODE_PAR_CHK));
|
||||
|
||||
return XS_NOERROR;
|
||||
}
|
||||
|
@ -1549,10 +1554,10 @@ ncr5380_msg_in(sc)
|
|||
register u_char icmd;
|
||||
|
||||
/* acknowledge phase change */
|
||||
*sc->sci_tcmd = PHASE_MSG_IN;
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_MSG_IN);
|
||||
|
||||
act_flags = ACT_CONTINUE;
|
||||
icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
|
||||
icmd = NCR5380_READ(sci_icmd) & SCI_ICMD_RMASK;
|
||||
|
||||
if (sc->sc_prevphase == PHASE_MSG_IN) {
|
||||
/* This is a continuation of the previous message. */
|
||||
|
@ -1590,7 +1595,7 @@ nextbyte:
|
|||
/* Just let ncr5380_machine() handle it... */
|
||||
return (act_flags);
|
||||
}
|
||||
phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
|
||||
phase = SCI_BUS_PHASE(NCR5380_READ(sci_bus_csr));
|
||||
if (phase != PHASE_MSG_IN) {
|
||||
/*
|
||||
* Target left MESSAGE IN, probably because it
|
||||
|
@ -1600,7 +1605,7 @@ nextbyte:
|
|||
return (act_flags);
|
||||
}
|
||||
/* Still in MESSAGE IN phase, and REQ is asserted. */
|
||||
if (*sc->sci_csr & SCI_CSR_PERR) {
|
||||
if (NCR5380_READ(sci_csr) & SCI_CSR_PERR) {
|
||||
ncr_sched_msgout(sc, SEND_PARITY_ERROR);
|
||||
sc->sc_state |= NCR_DROP_MSGIN;
|
||||
}
|
||||
|
@ -1611,7 +1616,7 @@ nextbyte:
|
|||
ncr_sched_msgout(sc, SEND_REJECT);
|
||||
sc->sc_state |= NCR_DROP_MSGIN;
|
||||
} else {
|
||||
*sc->sc_imp++ = *sc->sci_data;
|
||||
*sc->sc_imp++ = NCR5380_READ(sci_data);
|
||||
n++;
|
||||
/*
|
||||
* This testing is suboptimal, but most
|
||||
|
@ -1637,7 +1642,7 @@ nextbyte:
|
|||
|
||||
/* Ack the last byte read. */
|
||||
icmd |= SCI_ICMD_ACK;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
if (ncr5380_wait_not_req(sc)) {
|
||||
NCR_TRACE("msg_in: drop, stuck REQ, n=%d\n", n);
|
||||
|
@ -1645,7 +1650,7 @@ nextbyte:
|
|||
}
|
||||
|
||||
icmd &= ~SCI_ICMD_ACK;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
if (act_flags != ACT_CONTINUE)
|
||||
return (act_flags);
|
||||
|
@ -1738,7 +1743,7 @@ have_msg:
|
|||
|
||||
/* Ack the last byte read. */
|
||||
icmd |= SCI_ICMD_ACK;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
if (ncr5380_wait_not_req(sc)) {
|
||||
NCR_TRACE("msg_in: last, stuck REQ, n=%d\n", n);
|
||||
|
@ -1746,7 +1751,7 @@ have_msg:
|
|||
}
|
||||
|
||||
icmd &= ~SCI_ICMD_ACK;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
/* Go get the next message, if any. */
|
||||
if (act_flags == ACT_CONTINUE)
|
||||
|
@ -1784,7 +1789,7 @@ ncr5380_msg_out(sc)
|
|||
register u_char icmd, msg;
|
||||
|
||||
/* acknowledge phase change */
|
||||
*sc->sci_tcmd = PHASE_MSG_OUT;
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_MSG_OUT);
|
||||
|
||||
progress = 0; /* did we send any messages? */
|
||||
act_flags = ACT_CONTINUE;
|
||||
|
@ -1793,9 +1798,9 @@ ncr5380_msg_out(sc)
|
|||
* Set ATN. If we're just sending a trivial 1-byte message,
|
||||
* we'll clear ATN later on anyway. Also drive the data bus.
|
||||
*/
|
||||
icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
|
||||
icmd = NCR5380_READ(sci_icmd) & SCI_ICMD_RMASK;
|
||||
icmd |= (SCI_ICMD_ATN | SCI_ICMD_DATA);
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
if (sc->sc_prevphase == PHASE_MSG_OUT) {
|
||||
if (sc->sc_omp == sc->sc_omess) {
|
||||
|
@ -1922,7 +1927,7 @@ nextbyte:
|
|||
NCR_TRACE("msg_out: no REQ, n=%d\n", n);
|
||||
goto out;
|
||||
}
|
||||
phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
|
||||
phase = SCI_BUS_PHASE(NCR5380_READ(sci_bus_csr));
|
||||
if (phase != PHASE_MSG_OUT) {
|
||||
/*
|
||||
* Target left MESSAGE OUT, possibly to reject
|
||||
|
@ -1938,17 +1943,17 @@ nextbyte:
|
|||
/* Clear ATN before last byte if this is the last message. */
|
||||
if (n == 0 && sc->sc_msgpriq == 0) {
|
||||
icmd &= ~SCI_ICMD_ATN;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
/* 2 deskew delays */
|
||||
delay(2); /* XXX */
|
||||
}
|
||||
|
||||
/* Put data on the bus. */
|
||||
*sc->sci_odata = *--sc->sc_omp;
|
||||
NCR5380_WRITE(sci_odata,*--sc->sc_omp);
|
||||
|
||||
/* Raise ACK to tell target data is on the bus. */
|
||||
icmd |= SCI_ICMD_ACK;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
/* Wait for REQ to be negated. */
|
||||
if (ncr5380_wait_not_req(sc)) {
|
||||
|
@ -1958,7 +1963,7 @@ nextbyte:
|
|||
|
||||
/* Finally, drop ACK. */
|
||||
icmd &= ~SCI_ICMD_ACK;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
/* Stuck bus or something... */
|
||||
if (act_flags & ACT_RESET_BUS)
|
||||
|
@ -1984,7 +1989,7 @@ nextbyte:
|
|||
out:
|
||||
/* Stop driving the data bus. */
|
||||
icmd &= ~SCI_ICMD_DATA;
|
||||
*sc->sci_icmd = icmd;
|
||||
NCR5380_WRITE(sci_icmd,icmd);
|
||||
|
||||
if (!progress)
|
||||
act_flags |= ACT_RESET_BUS;
|
||||
|
@ -2006,7 +2011,7 @@ ncr5380_command(sc)
|
|||
int len;
|
||||
|
||||
/* acknowledge phase change */
|
||||
*sc->sci_tcmd = PHASE_COMMAND;
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_COMMAND);
|
||||
|
||||
if (sr->sr_flags & SR_SENSE) {
|
||||
rqs.opcode = REQUEST_SENSE;
|
||||
|
@ -2063,7 +2068,7 @@ ncr5380_data_xfer(sc, phase)
|
|||
goto abort;
|
||||
}
|
||||
/* acknowledge phase change */
|
||||
*sc->sci_tcmd = PHASE_DATA_IN;
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_DATA_IN);
|
||||
len = ncr5380_pio_in(sc, phase, sizeof(xs->sense.scsi_sense),
|
||||
(u_char *)&xs->sense.scsi_sense);
|
||||
return ACT_CONTINUE;
|
||||
|
@ -2094,7 +2099,7 @@ ncr5380_data_xfer(sc, phase)
|
|||
else
|
||||
ncr5380_pio_out(sc, phase, 4096, NULL);
|
||||
/* Make sure that caused a phase change. */
|
||||
if (SCI_BUS_PHASE(*sc->sci_bus_csr) == phase) {
|
||||
if (SCI_BUS_PHASE(NCR5380_READ(sci_bus_csr)) == phase) {
|
||||
/* More than 4k is just too much! */
|
||||
printf("%s: too much data padding\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
|
@ -2127,7 +2132,7 @@ ncr5380_data_xfer(sc, phase)
|
|||
*/
|
||||
NCR_TRACE("data_xfer: doing PIO, len=%d\n", sc->sc_datalen);
|
||||
/* acknowledge phase change */
|
||||
*sc->sci_tcmd = phase; /* XXX: OK for PDMA? */
|
||||
NCR5380_WRITE(sci_tcmd,phase); /* XXX: OK for PDMA? */
|
||||
if (phase == PHASE_DATA_OUT) {
|
||||
len = (*sc->sc_pio_out)(sc, phase, sc->sc_datalen, sc->sc_dataptr);
|
||||
} else {
|
||||
|
@ -2155,7 +2160,7 @@ ncr5380_status(sc)
|
|||
struct sci_req *sr = sc->sc_current;
|
||||
|
||||
/* acknowledge phase change */
|
||||
*sc->sci_tcmd = PHASE_STATUS;
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_STATUS);
|
||||
|
||||
len = ncr5380_pio_in(sc, PHASE_STATUS, 1, &status);
|
||||
if (len) {
|
||||
|
@ -2223,7 +2228,7 @@ next_phase:
|
|||
*/
|
||||
timo = ncr5380_wait_phase_timo;
|
||||
for (;;) {
|
||||
if (*sc->sci_bus_csr & SCI_BUS_REQ)
|
||||
if (NCR5380_READ(sci_bus_csr) & SCI_BUS_REQ)
|
||||
break;
|
||||
if (--timo <= 0) {
|
||||
if (sc->sc_state & NCR_ABORTING) {
|
||||
|
@ -2241,7 +2246,7 @@ next_phase:
|
|||
delay(100);
|
||||
}
|
||||
|
||||
phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
|
||||
phase = SCI_BUS_PHASE(NCR5380_READ(sci_bus_csr));
|
||||
NCR_TRACE("machine: phase=%s\n",
|
||||
(long) phase_names[phase & 7]);
|
||||
|
||||
|
@ -2256,7 +2261,7 @@ next_phase:
|
|||
* XXX: ... each phase routine does that itself.
|
||||
* In particular, DMA needs it done LATER.
|
||||
*/
|
||||
*sc->sci_tcmd = phase; /* acknowledge phase change */
|
||||
NCR5380_WRITE(sci_tcmd,phase); /* acknowledge phase change */
|
||||
#endif
|
||||
|
||||
switch (phase) {
|
||||
|
@ -2327,7 +2332,7 @@ do_actions:
|
|||
* Check for parity error.
|
||||
* XXX - better place to check?
|
||||
*/
|
||||
if (*(sc->sci_csr) & SCI_CSR_PERR) {
|
||||
if (NCR5380_READ(sci_csr) & SCI_CSR_PERR) {
|
||||
printf("%s: parity error!\n", sc->sc_dev.dv_xname);
|
||||
/* XXX: sc->sc_state |= NCR_ABORTING; */
|
||||
ncr_sched_msgout(sc, SEND_PARITY_ERROR);
|
||||
|
@ -2389,12 +2394,12 @@ do_actions:
|
|||
NCR_TRACE("machine: discon, waited %d\n",
|
||||
ncr5380_wait_req_timo - timo);
|
||||
|
||||
*sc->sci_icmd = 0;
|
||||
*sc->sci_mode = 0;
|
||||
*sc->sci_tcmd = PHASE_INVALID;
|
||||
*sc->sci_sel_enb = 0;
|
||||
NCR5380_WRITE(sci_icmd,0);
|
||||
NCR5380_WRITE(sci_mode,0);
|
||||
NCR5380_WRITE(sci_tcmd,PHASE_INVALID);
|
||||
NCR5380_WRITE(sci_sel_enb,0);
|
||||
SCI_CLR_INTR(sc);
|
||||
*sc->sci_sel_enb = 0x80;
|
||||
NCR5380_WRITE(sci_sel_enb,0x80);
|
||||
|
||||
if ((act_flags & ACT_CMD_DONE) == 0) {
|
||||
__asm("_ncr5380_disconnected:");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ncr5380var.h,v 1.8 1997/08/27 11:24:58 bouyer Exp $ */
|
||||
/* $NetBSD: ncr5380var.h,v 1.9 1998/10/25 17:26:41 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 David Jones, Gordon W. Ross
|
||||
|
@ -37,8 +37,35 @@
|
|||
* module and the machine-indepenedent ncr5380sbc.c module.
|
||||
*/
|
||||
|
||||
#define SCI_CLR_INTR(sc) (*(sc)->sci_iack)
|
||||
#define SCI_BUSY(sc) (*sc->sci_bus_csr & SCI_BUS_BSY)
|
||||
/*
|
||||
* Only the i386 uses real bus space:
|
||||
* arm32: oak and csa drivers; easy to convert
|
||||
* mac68k: sbc driver; easy to convert
|
||||
* pc532: ncr driver; need bus.h first
|
||||
* sparc: si and sw drivers; easy to convert
|
||||
* sun3: si driver; need bus.h first
|
||||
* vax: ncr driver; need bus.h first
|
||||
*/
|
||||
#ifdef __i386__
|
||||
# define NCR5380_USE_BUS_SPACE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handy read/write macros
|
||||
*/
|
||||
#if NCR5380_USE_BUS_SPACE
|
||||
# include <machine/bus.h>
|
||||
/* bus_space() variety */
|
||||
# define NCR5380_READ(reg) bus_space_read_1(sc->iot,sc->ioh,sc->reg)
|
||||
# define NCR5380_WRITE(reg,val) bus_space_write_1(sc->iot,sc->ioh,sc->reg,val)
|
||||
#else
|
||||
/* legacy memory-mapped variety */
|
||||
# define NCR5380_READ(reg) *sc->reg
|
||||
# define NCR5380_WRITE(reg,val) *(sc->reg) = val
|
||||
#endif
|
||||
|
||||
#define SCI_CLR_INTR(sc) NCR5380_READ(sci_iack)
|
||||
#define SCI_BUSY(sc) (NCR5380_READ(sci_bus_csr) & SCI_BUS_BSY)
|
||||
|
||||
/* These are NOT artibtrary, but map to bits in sci_tcmd */
|
||||
#define PHASE_DATA_OUT 0x0
|
||||
|
@ -76,9 +103,24 @@ struct sci_req {
|
|||
|
||||
|
||||
struct ncr5380_softc {
|
||||
struct device sc_dev;
|
||||
struct scsipi_link sc_link;
|
||||
struct device sc_dev;
|
||||
struct scsipi_link sc_link;
|
||||
|
||||
#ifdef NCR5380_USE_BUS_SPACE
|
||||
/* Pointers to bus_space */
|
||||
bus_space_tag_t iot;
|
||||
bus_space_handle_t ioh;
|
||||
|
||||
/* Pointers to 5380 registers. */
|
||||
bus_size_t sci_r0;
|
||||
bus_size_t sci_r1;
|
||||
bus_size_t sci_r2;
|
||||
bus_size_t sci_r3;
|
||||
bus_size_t sci_r4;
|
||||
bus_size_t sci_r5;
|
||||
bus_size_t sci_r6;
|
||||
bus_size_t sci_r7;
|
||||
#else
|
||||
/* Pointers to 5380 registers. See ncr5380reg.h */
|
||||
volatile u_char *sci_r0;
|
||||
volatile u_char *sci_r1;
|
||||
|
@ -88,6 +130,7 @@ struct ncr5380_softc {
|
|||
volatile u_char *sci_r5;
|
||||
volatile u_char *sci_r6;
|
||||
volatile u_char *sci_r7;
|
||||
#endif
|
||||
|
||||
/* Functions set from MD code */
|
||||
int (*sc_pio_out) __P((struct ncr5380_softc *,
|
||||
|
|
Loading…
Reference in New Issue