* Add command struct and modifier definitions for controlling the

ISA-compatible port space of PCI buslogic cards.

* Add call to bha_pci.c to disable the ISA-compatible ports of a PCI
  device.  The ISA-compatible ports are enabled by default, which
  causes the card to be autoconfigured a second time as an ISA device,
  which appears to deadlock the card.

* Change bha_cmd() to return the number of bytes it actually received
  in response to a command, or -1 on error.

*  Use heuristics (checking for bha-only registers, and checking the size
   of the response to BHA_INQURE_EXTENDED) to bha_find, to make sure the
   bha driver never matches an aha (Adaptec    1542 or compatible) device.

A single kernel should now boot on either Adaptec or BusLogic controllers,
provided we always probe for BusLogic devices before Adaptec devices,
but this has not yet been verified.
This commit is contained in:
jonathan 1996-11-05 03:04:28 +00:00
parent dd7ad6d7b8
commit 79b026a8f3
4 changed files with 101 additions and 17 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: bha.c,v 1.4 1996/10/21 22:34:11 thorpej Exp $ */
/* $NetBSD: bha.c,v 1.5 1996/11/05 03:04:28 jonathan Exp $ */
#undef BHADIAG
#ifdef DDB
@ -82,8 +82,8 @@
int bha_debug = 0;
#endif /* BHADEBUG */
int bha_cmd __P((bus_space_tag_t, bus_space_handle_t, struct bha_softc *,
int, u_char *, int, u_char *));
int bha_cmd __P((bus_space_tag_t, bus_space_handle_t, struct bha_softc *,
int, u_char *, int, u_char *));
integrate void bha_finish_ccbs __P((struct bha_softc *));
integrate void bha_reset_ccb __P((struct bha_softc *, struct bha_ccb *));
void bha_free_ccb __P((struct bha_softc *, struct bha_ccb *));
@ -150,6 +150,7 @@ bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
int wait;
u_char sts;
u_char opcode = ibuf[0];
int rbytes; /* bytes returned in obuf */
if (sc != NULL)
name = sc->sc_dev.dv_xname;
@ -182,7 +183,7 @@ bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
if (!i) {
printf("%s: bha_cmd, host not idle(0x%x)\n",
name, sts);
return (1);
return (-1);
}
}
/*
@ -211,7 +212,7 @@ bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
name);
bus_space_write_1(iot, ioh, BHA_CTRL_PORT,
BHA_CTRL_SRST);
return (1);
return (-1);
}
bus_space_write_1(iot, ioh, BHA_CMD_PORT, *ibuf++);
}
@ -219,7 +220,8 @@ bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
* If we expect input, loop that many times, each time,
* looking for the data register to have valid data
*/
while (ocnt--) {
rbytes = 0;
while (rbytes < ocnt) {
for (i = wait; i; i--) {
sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
if (sts & BHA_STAT_DF)
@ -232,9 +234,10 @@ bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
name, ocnt);
bus_space_write_1(iot, ioh, BHA_CTRL_PORT,
BHA_CTRL_SRST);
return (1);
return (-1);
}
*obuf++ = bus_space_read_1(iot, ioh, BHA_DATA_PORT);
rbytes++;
}
/*
* Wait for the board to report a finished instruction.
@ -252,11 +255,11 @@ bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
if (!i) {
printf("%s: bha_cmd, host not finished(0x%x)\n",
name, sts);
return (1);
return (-1);
}
}
bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
return (0);
return (rbytes);
}
/*
@ -727,8 +730,13 @@ bha_find(iot, ioh, sc)
struct bha_config config;
int irq, drq;
/* Check something is at the ports we need to access */
sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
if (sts == 0xFF)
return (0);
/*
* reset board, If it doesn't respond, assume
* Reset board, If it doesn't respond, assume
* that it's not there.. good for the probe
*/
@ -750,18 +758,52 @@ bha_find(iot, ioh, sc)
return (0);
}
/*
* The BusLogic cards implement an Adaptec 1542 (aha)-compatible
* interface. The native bha interface is not compatible with
* an aha. 1542. We need to ensure that we never match an
* Adaptec 1542. We must also avoid sending Adaptec-compatible
* commands to a real bha, lest it go into 1542 emulation mode.
* (On an indirect bus like ISA, we should always probe for BusLogic
* interfaces before Adaptec interfaces).
*/
/*
* Make sure we don't match an AHA-1542A or AHA-1542B, by checking
* for an extended-geometry register. The 1542[AB] don't have one.
*/
sts = bus_space_read_1(iot, ioh, BHA_EXTGEOM_PORT);
if (sts == 0xFF)
return (0);
/*
* Check that we actually know how to use this board.
*/
delay(1000);
inquire.cmd.opcode = BHA_INQUIRE_EXTENDED;
inquire.cmd.len = sizeof(inquire.reply);
bha_cmd(iot, ioh, sc,
sizeof(inquire.cmd), (u_char *)&inquire.cmd,
sizeof(inquire.reply), (u_char *)&inquire.reply);
i = bha_cmd(iot, ioh, sc,
sizeof(inquire.cmd), (u_char *)&inquire.cmd,
sizeof(inquire.reply), (u_char *)&inquire.reply);
/*
* Some 1542Cs (CP, perhaps not CF, may depend on firmware rev)
* have the extended-geometry register and also respond to
* BHA_INQUIRE_EXTENDED. Make sure we never match such cards,
* by checking the size of the reply is what a BusLogic card returns.
*/
if (i != sizeof(inquire.reply)) {
#ifdef BHADEBUG
printf("bha_find: board returned %d instead of %d to %s\n",
i, sizeof(inquire.reply), "INQUIRE_EXTENDED");
#endif
return (0);
}
/* OK, we know we've found a buslogic adaptor. */
switch (inquire.reply.bus_type) {
case BHA_BUS_TYPE_24BIT:
/* XXXX How do we avoid conflicting with the aha1542 probe? */
case BHA_BUS_TYPE_32BIT:
break;
case BHA_BUS_TYPE_MCA:
@ -839,6 +881,26 @@ bha_find(iot, ioh, sc)
return (1);
}
/*
* Disable the ISA-compatiblity ioports on PCI bha devices,
* to ensure they're not autoconfigured a second time as an ISA bha.
*/
int
bha_disable_isacompat(sc)
struct bha_softc *sc;
{
struct bha_isadisable isa_disable;
isa_disable.cmd.opcode = BHA_MODIFY_IOPORT;
isa_disable.cmd.modifier = BHA_IOMODIFY_DISABLE1;
bha_cmd(sc->sc_iot, sc->sc_ioh, sc,
sizeof(isa_disable.cmd), (u_char*)&isa_disable.cmd,
0, 0);
return (0);
}
/*
* Start the board, ready for normal operation
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: bhareg.h,v 1.2 1996/09/01 00:54:36 mycroft Exp $ */
/* $NetBSD: bhareg.h,v 1.3 1996/11/05 03:04:31 jonathan Exp $ */
/*
* Copyright (c) 1994, 1996 Charles M. Hannum. All rights reserved.
@ -57,6 +57,7 @@ typedef u_int8_t physlen[4];
#define BHA_CMD_PORT 1 /* command (wo) */
#define BHA_DATA_PORT 1 /* data (ro) */
#define BHA_INTR_PORT 2 /* interrupt status (ro) */
#define BHA_EXTGEOM_PORT 2 /* extended geometry (ro) */
/*
* BHA_CTRL bits
@ -104,6 +105,8 @@ typedef u_int8_t physlen[4];
#define BHA_INQUIRE_PERIOD 0x8c /* Get synchronous period */
#define BHA_INQUIRE_EXTENDED 0x8d /* Adapter Setup Inquiry */
#define BHA_ROUND_ROBIN 0x8f /* Enable/Disable(default) round robin */
#define BHA_MODIFY_IOPORT 0x95 /* change or disable I/O port */
/*
* BHA_INTR bits
@ -340,6 +343,21 @@ struct bha_period {
} reply;
};
struct bha_isadisable {
struct {
u_char opcode;
u_char modifier;
} cmd;
};
/*
* bha_isadisable.modifier parameters
*/
#define BHA_IOMODIFY_330 0x00
#define BHA_IOMODIFY_334 0x01
#define BHA_IOMODIFY_DISABLE1 0x06
#define BHA_IOMODIFY_DISABLE2 0x07
#define INT9 0x01
#define INT10 0x02
#define INT11 0x04

View File

@ -1,4 +1,4 @@
/* $NetBSD: bhavar.h,v 1.3 1996/10/21 22:34:13 thorpej Exp $ */
/* $NetBSD: bhavar.h,v 1.4 1996/11/05 03:04:33 jonathan Exp $ */
/*
* Copyright (c) 1994, 1996 Charles M. Hannum. All rights reserved.
@ -78,3 +78,5 @@ int bha_find __P((bus_space_tag_t, bus_space_handle_t,
struct bha_softc *));
void bha_attach __P((struct bha_softc *));
int bha_intr __P((void *));
int bha_disable_isacompat __P((struct bha_softc *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: bha_pci.c,v 1.5 1996/10/21 22:56:27 thorpej Exp $ */
/* $NetBSD: bha_pci.c,v 1.6 1996/11/05 03:04:36 jonathan Exp $ */
/*
* Copyright (c) 1994, 1996 Charles M. Hannum. All rights reserved.
@ -151,4 +151,6 @@ bha_pci_attach(parent, self, aux)
printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
bha_attach(sc);
bha_disable_isacompat(sc);
}