Subject: Fixed bt/aha patches
To: None <port-i386@NetBSD.ORG>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: port-i386
Date: 01/04/1997 10:59:27
Please ignore the previous patches. They won't work.
i forgot that 1.2 (at least the source tree I have) doesn't
have extent-based IOport accounting.
To avoid configuring bha devices as aha's, the aha driver needs
to be changed to also reject bha devices. (The sense of
the return value from aha_find and bha_find has also changed
since 1.2, so the previous patch was very broken.)
That also makes the relative order of bha and aha probing immaterial,
so I deleted the change to sys/dev/isa/files.isa.
The following works for me on a bha device; basically, I applied
the bt changes to the aha driver and reversed the sense of the test.
If someone could test it on an aha 154x, that would be great.
*** sys/dev/isa/bt.c-1.2 Mon May 13 04:36:16 1996
--- sys/dev/isa/bt.c Sat Jan 4 10:25:41 1997
***************
*** 200,205 ****
--- 200,206 ----
int wait;
u_char sts;
u_char opcode = ibuf[0];
+ int rbytes; /* count of bytes actually returned in obuf */
if (sc != NULL)
name = sc->sc_dev.dv_xname;
***************
*** 232,238 ****
if (!i) {
printf("%s: bt_cmd, host not idle(0x%x)\n",
name, sts);
! return ENXIO;
}
}
/*
--- 233,239 ----
if (!i) {
printf("%s: bt_cmd, host not idle(0x%x)\n",
name, sts);
! return (-1);
}
}
/*
***************
*** 258,264 ****
if (opcode != BT_INQUIRE_REVISION)
printf("%s: bt_cmd, cmd/data port full\n", name);
outb(iobase + BT_CTRL_PORT, BT_CTRL_SRST);
! return ENXIO;
}
outb(iobase + BT_CMD_PORT, *ibuf++);
}
--- 259,265 ----
if (opcode != BT_INQUIRE_REVISION)
printf("%s: bt_cmd, cmd/data port full\n", name);
outb(iobase + BT_CTRL_PORT, BT_CTRL_SRST);
! return (-1);
}
outb(iobase + BT_CMD_PORT, *ibuf++);
}
***************
*** 266,272 ****
* If we expect input, loop that many times, each time,
* looking for the data register to have valid data
*/
! while (ocnt--) {
for (i = wait; i; i--) {
sts = inb(iobase + BT_STAT_PORT);
if (sts & BT_STAT_DF)
--- 267,274 ----
* If we expect input, loop that many times, each time,
* looking for the data register to have valid data
*/
! rbytes = 0;
! while (rbytes < ocnt) {
for (i = wait; i; i--) {
sts = inb(iobase + BT_STAT_PORT);
if (sts & BT_STAT_DF)
***************
*** 278,286 ****
printf("%s: bt_cmd, cmd/data port empty %d\n",
name, ocnt);
outb(iobase + BT_CTRL_PORT, BT_CTRL_SRST);
! return ENXIO;
}
*obuf++ = inb(iobase + BT_DATA_PORT);
}
/*
* Wait for the board to report a finished instruction.
--- 280,289 ----
printf("%s: bt_cmd, cmd/data port empty %d\n",
name, ocnt);
outb(iobase + BT_CTRL_PORT, BT_CTRL_SRST);
! return (-1);
}
*obuf++ = inb(iobase + BT_DATA_PORT);
+ rbytes++;
}
/*
* Wait for the board to report a finished instruction.
***************
*** 298,308 ****
if (!i) {
printf("%s: bt_cmd, host not finished(0x%x)\n",
name, sts);
! return ENXIO;
}
}
outb(iobase + BT_CTRL_PORT, BT_CTRL_IRST);
! return 0;
}
/*
--- 301,311 ----
if (!i) {
printf("%s: bt_cmd, host not finished(0x%x)\n",
name, sts);
! return (-1);
}
}
outb(iobase + BT_CTRL_PORT, BT_CTRL_IRST);
! return (rbytes);
}
/*
***************
*** 805,811 ****
}
/*
! * Find the board and find it's irq/drq
*/
int
bt_find(ia, sc)
--- 808,815 ----
}
/*
! * Find the board and find it's irq/drq.
! * returns 0 if device found, 1 otherwise.
*/
int
bt_find(ia, sc)
***************
*** 819,824 ****
--- 823,833 ----
struct bt_config config;
int irq, drq;
+ /* Check something is at the ports we need to access */
+ sts = inb(iobase + BT_STAT_PORT);
+ if (sts == 0xFF)
+ return (1);
+
/*
* reset board, If it doesn't respond, assume
* that it's not there.. good for the probe
***************
*** 842,854 ****
}
/*
* Check that we actually know how to use this board.
*/
delay(1000);
inquire.cmd.opcode = BT_INQUIRE_EXTENDED;
inquire.cmd.len = sizeof(inquire.reply);
! bt_cmd(iobase, sc, sizeof(inquire.cmd), (u_char *)&inquire.cmd,
sizeof(inquire.reply), (u_char *)&inquire.reply);
switch (inquire.reply.bus_type) {
case BT_BUS_TYPE_24BIT:
/* XXXX How do we avoid conflicting with the aha1542 probe? */
--- 851,898 ----
}
/*
+ * 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 = inb(iobase + BT_EXTGEOM_PORT);
+ if (sts == 0xFF)
+ return (1);
+
+ /*
* Check that we actually know how to use this board.
*/
delay(1000);
inquire.cmd.opcode = BT_INQUIRE_EXTENDED;
inquire.cmd.len = sizeof(inquire.reply);
! i = bt_cmd(iobase, 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
+ * BT_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("bt_find: board returned %d instead of %d to %s\n",
+ i, sizeof(inquire.reply), "INQUIRE_EXTENDED");
+ #endif
+ return (1);
+ }
+
+ /* OK, we've found a buslogic adapter. */
+
switch (inquire.reply.bus_type) {
case BT_BUS_TYPE_24BIT:
/* XXXX How do we avoid conflicting with the aha1542 probe? */
*** sys/dev/isa/btreg.h-1.2 Thu May 2 04:42:25 1996
--- sys/dev/isa/btreg.h Sat Jan 4 10:46:06 1997
***************
*** 1,8 ****
--- 1,12 ----
+ #ifndef ltophys
+
typedef u_int8_t physaddr[4];
typedef u_int8_t physlen[4];
#define ltophys _lto4l
#define phystol _4ltol
+ #endif
+
/*
* I/O port offsets
*/
***************
*** 11,16 ****
--- 15,21 ----
#define BT_CMD_PORT 1 /* command (wo) */
#define BT_DATA_PORT 1 /* data (ro) */
#define BT_INTR_PORT 2 /* interrupt status (ro) */
+ #define BT_EXTGEOM_PORT 3 /* extended geometry(ro) */
/*
* BT_CTRL bits
***************
*** 188,194 ****
#define BT_BUS_TYPE_32BIT 'E' /* EISA/VLB/PCI bus */
#define BT_BUS_TYPE_MCA 'M' /* MicroChannel bus */
u_char bios_address; /* Address of adapter BIOS */
! u_short max_segment; /* ? */
} reply;
};
--- 193,210 ----
#define BT_BUS_TYPE_32BIT 'E' /* EISA/VLB/PCI bus */
#define BT_BUS_TYPE_MCA 'M' /* MicroChannel bus */
u_char bios_address; /* Address of adapter BIOS */
! u_short sg_limit;
! u_char mbox_count;
! u_char mbox_baseaddr[4]; /* packed/unaligned uint_32_t */
! u_char intrflags;
! #define BHA_INTR_LEVEL 0x40 /* bit 6: level-sensitive interrupt */
! u_char firmware_level[3]; /* last 3 digits of firmware rev */
! u_char scsi_flags; /* supported SCSI features */
! #define BHA_SCSI_WIDE 0x01
! #define BHA_SCSI_DIFFERENTIAL 0x02
! #define BHA_SCSI_AUTOCONF 0x04
! #define BHA_SCSI_ULTRA 0x08
! #define BHA_SCSI_TERMINATION 0x10
} reply;
};
*** sys/dev/isa/aha.c-1.2 Mon May 13 04:36:13 1996
--- sys/dev/isa/aha.c Sat Jan 4 10:47:17 1997
***************
*** 68,73 ****
--- 68,74 ----
#include <dev/isa/isavar.h>
#include <dev/isa/isadmavar.h>
#include <dev/isa/ahareg.h>
+ #include <dev/isa/btreg.h> /* Avoid aha154x-compat mode of buslogic cards */
#ifndef DDB
#define Debugger() panic("should call debugger here (aha1542.c)")
***************
*** 200,205 ****
--- 201,207 ----
int wait;
u_char sts;
u_char opcode = ibuf[0];
+ int rbytes; /* count of bytes actually returned in obuf */
if (sc != NULL)
name = sc->sc_dev.dv_xname;
***************
*** 232,238 ****
if (!i) {
printf("%s: aha_cmd, host not idle(0x%x)\n",
name, sts);
! return ENXIO;
}
}
/*
--- 234,240 ----
if (!i) {
printf("%s: aha_cmd, host not idle(0x%x)\n",
name, sts);
! return (-1);
}
}
/*
***************
*** 258,264 ****
if (opcode != AHA_INQUIRE_REVISION)
printf("%s: aha_cmd, cmd/data port full\n", name);
outb(iobase + AHA_CTRL_PORT, AHA_CTRL_SRST);
! return ENXIO;
}
outb(iobase + AHA_CMD_PORT, *ibuf++);
}
--- 260,266 ----
if (opcode != AHA_INQUIRE_REVISION)
printf("%s: aha_cmd, cmd/data port full\n", name);
outb(iobase + AHA_CTRL_PORT, AHA_CTRL_SRST);
! return (-1);
}
outb(iobase + AHA_CMD_PORT, *ibuf++);
}
***************
*** 266,272 ****
* If we expect input, loop that many times, each time,
* looking for the data register to have valid data
*/
! while (ocnt--) {
for (i = wait; i; i--) {
sts = inb(iobase + AHA_STAT_PORT);
if (sts & AHA_STAT_DF)
--- 268,275 ----
* If we expect input, loop that many times, each time,
* looking for the data register to have valid data
*/
! rbytes = 0;
! while (rbytes < ocnt) {
for (i = wait; i; i--) {
sts = inb(iobase + AHA_STAT_PORT);
if (sts & AHA_STAT_DF)
***************
*** 278,287 ****
printf("%s: aha_cmd, cmd/data port empty %d\n",
name, ocnt);
outb(iobase + AHA_CTRL_PORT, AHA_CTRL_SRST);
! return ENXIO;
}
*obuf++ = inb(iobase + AHA_DATA_PORT);
}
/*
* Wait for the board to report a finished instruction.
* We may get an extra interrupt for the HACC signal, but this is
--- 281,292 ----
printf("%s: aha_cmd, cmd/data port empty %d\n",
name, ocnt);
outb(iobase + AHA_CTRL_PORT, AHA_CTRL_SRST);
! return (-1);
}
*obuf++ = inb(iobase + AHA_DATA_PORT);
+ rbytes++;
}
+
/*
* Wait for the board to report a finished instruction.
* We may get an extra interrupt for the HACC signal, but this is
***************
*** 298,308 ****
if (!i) {
printf("%s: aha_cmd, host not finished(0x%x)\n",
name, sts);
! return ENXIO;
}
}
outb(iobase + AHA_CTRL_PORT, AHA_CTRL_IRST);
! return 0;
}
/*
--- 303,313 ----
if (!i) {
printf("%s: aha_cmd, host not finished(0x%x)\n",
name, sts);
! return (-1);
}
}
outb(iobase + AHA_CTRL_PORT, AHA_CTRL_IRST);
! return rbytes;
}
/*
***************
*** 806,812 ****
}
/*
! * Find the board and find its irq/drq
*/
int
aha_find(ia, sc)
--- 811,818 ----
}
/*
! * Find the board and find its irq/drq.
! * return 0 if a board is found, 1 otherwise.
*/
int
aha_find(ia, sc)
***************
*** 818,823 ****
--- 824,830 ----
u_char sts;
struct aha_config config;
int irq, drq;
+ struct bt_extended_inquire inquire; /* to detect bha devices */
/*
* reset board, If it doesn't respond, assume
***************
*** 838,843 ****
--- 845,872 ----
if (aha_debug)
printf("aha_find: No answer from adaptec board\n");
#endif /* AHADEBUG */
+ return 1;
+ }
+
+ /*
+ /*
+ * Make sure this isn't a BusLogic card.
+ * Some 1542Cs (CP, perhaps not CF, may depend on firmware rev)
+ * have the extended-geometry register and also respond to
+ * BT_INQUIRE_EXTENDED. Make sure we never match such cards,
+ * by checking the size of the reply is what a BusLogic card returns.
+ */
+ delay(1000);
+ inquire.cmd.opcode = BT_INQUIRE_EXTENDED;
+ inquire.cmd.len = sizeof(inquire.reply);
+ i = bt_cmd(iobase, sc, sizeof(inquire.cmd), (u_char *)&inquire.cmd,
+ sizeof(inquire.reply), (u_char *)&inquire.reply);
+
+ if (i == sizeof(inquire.reply)) {
+ #ifdef AHADEBUG
+ printf("aha_find: board returned %d instead of %d to %s\n",
+ i, sizeof(inquire.reply), "INQUIRE_EXTENDED");
+ #endif
return 1;
}