diff options
author | gibbs <gibbs@FreeBSD.org> | 1996-05-10 16:26:41 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 1996-05-10 16:26:41 +0000 |
commit | c0934bc4abadb7b0f372da387f132f64f607c58f (patch) | |
tree | 04862cf800b046c9f3266a01a8fa00b7e6f879fe /sys/pci | |
parent | 40c5caf145aecb72b47ec8e18e74e2e21a462565 (diff) | |
download | FreeBSD-src-c0934bc4abadb7b0f372da387f132f64f607c58f.zip FreeBSD-src-c0934bc4abadb7b0f372da387f132f64f607c58f.tar.gz |
The aic78X0 cards have 0xff in all bytes of scratch ram after POST. If
a BIOS was not installed, this will still be true by the time we probe
the chip. We use this heuristic to determine if we should use the left
over scratch ram target settings for controllers that don't have an
SEEPROM. We also "snapshot" the host adapter SCSI id and whether ultra
is enabled or not and use these values if a BIOS was installed. The card
will act as if a BIOS was installed even if there wasn't one if you warm
reboot, but since the scratch ram area is still valid in this case, its
hardly worth the effort of writing a shutdown routing that clears out
the scratch ram. This should make users of motherboard controllers
happy.
Diffstat (limited to 'sys/pci')
-rw-r--r-- | sys/pci/aic7870.c | 88 |
1 files changed, 58 insertions, 30 deletions
diff --git a/sys/pci/aic7870.c b/sys/pci/aic7870.c index cbe7ba0..cdd2c1e 100644 --- a/sys/pci/aic7870.c +++ b/sys/pci/aic7870.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7870.c,v 1.28 1996/03/31 03:17:46 gibbs Exp $ + * $Id: aic7870.c,v 1.29 1996/04/20 21:31:27 gibbs Exp $ */ #include <pci.h> @@ -152,7 +152,7 @@ struct seeprom_config { static char* aic7870_probe __P((pcici_t tag, pcidi_t type)); static void aic7870_attach __P((pcici_t config_id, int unit)); -static int load_seeprom __P((struct ahc_data *ahc)); +static void load_seeprom __P((struct ahc_data *ahc)); static int acquire_seeprom __P((u_long offset, u_short CS, u_short CK, u_short DO, u_short DI, u_short RDY, u_short MS)); @@ -227,6 +227,8 @@ aic7870_attach(config_id, unit) ahc_type ahc_t = AHC_NONE; ahc_flag ahc_f = AHC_FNONE; struct ahc_data *ahc; + u_char ultra_enb = 0; + u_char our_id = 0; if(!(io_port = pci_conf_read(config_id, PCI_BASEADR0))) return; @@ -276,6 +278,11 @@ aic7870_attach(config_id, unit) /* On all PCI adapters, we allow SCB paging */ ahc_f |= AHC_PAGESCBS; + /* Remeber how the card was setup in case there is no SEEPROM */ + our_id = inb(SCSIID + io_port) & OID; + if(ahc_t & AHC_ULTRA) + ultra_enb = inb(SXFRCTL0 + io_port) & ULTRAEN; + ahc_reset(io_port); if(ahc_t & AHC_AIC7870){ @@ -371,14 +378,20 @@ aic7870_attach(config_id, unit) case AHC_AIC7860: { id_string = "aic7860 "; - /* Assume there is no BIOS for these cards? */ + /* + * Use defaults, if the chip wasn't initialized by + * a BIOS. + */ ahc->flags |= AHC_USEDEFAULTS; break; } case AHC_AIC7850: { id_string = "aic7850 "; - /* Assume there is no BIOS for these cards? */ + /* + * Use defaults, if the chip wasn't initialized by + * a BIOS. + */ ahc->flags |= AHC_USEDEFAULTS; break; } @@ -390,8 +403,6 @@ aic7870_attach(config_id, unit) } } - printf("ahc%d: %s", unit, id_string); - /* * Take the LED out of diagnostic mode */ @@ -408,13 +419,36 @@ aic7870_attach(config_id, unit) /* * PCI Adapter default setup * Should only be used if the adapter does not have - * an SEEPROM and we don't think a BIOS was installed. + * an SEEPROM. */ - /* Set the host ID */ - outb(SCSICONF + iobase, 7); + /* See if someone else set us up already */ + u_long i; + for(i=io_port + TARG_SCRATCH; i < io_port + 0x60; i++) { + if(inb(i) != 0xff) + break; + } + if(i != io_port + 0x60) { + printf("ahc%d: Using left over BIOS settings\n", + ahc->unit); + ahc->flags &= ~AHC_USEDEFAULTS; + } + else + our_id = 0x07; + outb(SCSICONF, (our_id & 0x07)|ENSPCHK|RESET_SCSI); /* In case we are a wide card */ - outb(SCSICONF + 1 + iobase, 7); + outb(SCSICONF + 1, our_id); + + if(!ultra_enb || (ahc->flags & AHC_USEDEFAULTS)) { + /* + * If there wasn't a BIOS or the board + * wasn't in this mode to begin with, + * turn off ultra. + */ + ahc->type &= ~AHC_ULTRA; + } } + + printf("ahc%d: %s", unit, id_string); } if(ahc_init(ahc)){ @@ -431,7 +465,7 @@ aic7870_attach(config_id, unit) /* * Read the SEEPROM. Return 0 on failure */ -int +void load_seeprom(ahc) struct ahc_data *ahc; { @@ -441,7 +475,7 @@ load_seeprom(ahc) u_long iobase = ahc->baseport; u_char scsi_conf; u_char host_id; - int have_seeprom, retval; + int have_seeprom; if(bootverbose) printf("ahc%d: Reading SEEPROM...", ahc->unit); @@ -462,7 +496,8 @@ load_seeprom(ahc) for (i = 0;i < (sizeof(sc)/2 - 1);i = i + 1) checksum = checksum + scarray[i]; if (checksum != sc.checksum) { - printf ("checksum error"); + if(bootverbose) + printf ("checksum error"); have_seeprom = 0; } else if(bootverbose) @@ -470,17 +505,9 @@ load_seeprom(ahc) } } if (!have_seeprom) { - printf("\nahc%d: SEEPROM read failed, " - "using leftover BIOS values\n", ahc->unit); - retval = 0; - - host_id = 0x7; - scsi_conf = host_id | ENSPCHK; /* Assume a default */ - /* - * If we happen to be an ULTRA card, - * default to non-ultra mode. - */ - ahc->type &= ~AHC_ULTRA; + if(bootverbose) + printf("\nahc%d: No SEEPROM availible\n", ahc->unit); + ahc->flags |= AHC_USEDEFAULTS; } else { /* @@ -509,6 +536,8 @@ load_seeprom(ahc) scsi_conf = (host_id & 0x7); if(sc.adapter_control & CFSPARITY) scsi_conf |= ENSPCHK; + if(sc.adapter_control & CFRESETB) + scsi_conf |= RESET_SCSI; if(ahc->type & AHC_ULTRA) { /* Should we enable Ultra mode? */ @@ -516,14 +545,13 @@ load_seeprom(ahc) /* Treat us as a non-ultra card */ ahc->type &= ~AHC_ULTRA; } - retval = 1; + /* Set the host ID */ + outb(SCSICONF + iobase, scsi_conf); + /* In case we are a wide card */ + outb(SCSICONF + 1 + iobase, host_id); } - /* Set the host ID */ - outb(SCSICONF + iobase, scsi_conf); - /* In case we are a wide card */ - outb(SCSICONF + 1 + iobase, host_id); - return(retval); + return; } static int |