Subject: Volunteers wanted to test backpatch of bt/aha probe changes to 1.2
To: None <port-i386@NetBSD.ORG>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: port-i386
Date: 01/04/1997 09:17:54
The following patch is a back-port of some changes made to
NetBSD-current late last year, to make kernels configured
for both BusLogic and Adaptec 154x SCSI controllers work.

The changes in -current have verified to work. The patches below
compiled, but are untested. If someone  running 1.2 on an i386
with either the "bt"  or "aha" driver could test out these changes,
they can be folded into a 1.2 patch release.  That would eliminate
the split  bt/aha kernel configs from future  1.2-based releases,
making NetBSD/i386 installation somewhat easier.

To test these changes, you'd need to patch them into your
kernel source tree and configure a kernel with both aha and bt
devices.  You could configure and compile a GENERIC kernel,
or add whichever of the "bt" or "aha" configurations your
own kernel doesn't already have (e.g., by cutting and pasting from
sys/arch/i386/config/GENERIC to your own config file).

Diffs follow.

--Jonathan



*** sys/dev/isa/bt.c-1.2	Mon May 13 04:36:16 1996
--- sys/dev/isa/bt.c	Sat Jan  4 08:48:29 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);
  }
  
  /*
***************
*** 819,824 ****
--- 822,832 ----
  	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 (0);
+ 
  	/*
  	 * 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? */
--- 850,897 ----
  	}
  
  	/*
+ 	 * 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 (0);
+ 
+ 	/*
  	 * 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 (0);
+ 	}
+ 
+ 	/* 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 08:47:30 1997
***************
*** 11,16 ****
--- 11,17 ----
  #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;
  };
  
--- 189,206 ----
  #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/files.isa-1.2	Thu May 16 11:16:36 1996
--- sys/dev/isa/files.isa	Sat Jan  4 08:32:20 1997
***************
*** 64,69 ****
--- 64,76 ----
  # SCSI host adapters
  #
  
+ # BusLogic BT-74x EISA family (XXX; should be PCI, EISA.  it's special)
+ # XXX must come before aha in ioconf.c or aha driver will attach bt devices.
+ device	bt: scsi, isadma
+ attach	bt at isa
+ file	dev/isa/bt.c			bt
+ 
+ 
  # Adaptec AHA-154x family
  device	aha: scsi, isadma
  attach	aha at isa
***************
*** 73,83 ****
  device	aic: scsi, isadma
  attach	aic at isa
  file	dev/isa/aic6360.c		aic
- 
- # BusLogic BT-74x EISA family (XXX; should be EISA.  it's special)
- device	bt: scsi, isadma
- attach	bt at isa
- file	dev/isa/bt.c			bt
  
  # Seagate ST0[12] ICs
  device	sea: scsi, isadma
--- 80,85 ----