aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJustin T. Gibbs <gibbs@FreeBSD.org>1999-12-06 18:29:03 +0000
committerJustin T. Gibbs <gibbs@FreeBSD.org>1999-12-06 18:29:03 +0000
commit820379186bbe4943772455044e62b1f80aea6e4b (patch)
tree47ee5410dbf719fcbe938b18467438dcac3c7ec8 /sys/dev
parentc2af6f650c4eb0f16a2f41bc527c7d2a85b45039 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/aic7xxx/ahc_pci.c91
1 files changed, 52 insertions, 39 deletions
diff --git a/sys/dev/aic7xxx/ahc_pci.c b/sys/dev/aic7xxx/ahc_pci.c
index fd91f5e1a0dc2..78a6ce4259d44 100644
--- a/sys/dev/aic7xxx/ahc_pci.c
+++ b/sys/dev/aic7xxx/ahc_pci.c
@@ -175,7 +175,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
},
/* aic7859 based controllers */
{
- ID_AHA_2930CU,
+ ID_AHA_2930CU & ID_DEV_VENDOR_MASK,
ID_DEV_VENDOR_MASK,
"Adaptec 2930CU SCSI adapter",
ahc_aic7859_setup
@@ -194,7 +194,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
ahc_aic7860_setup
},
{
- ID_AHA_2930C_VAR,
+ ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK,
ID_DEV_VENDOR_MASK,
"Adaptec 2930C SCSI adapter (VAR)",
ahc_aic7860_setup
@@ -467,8 +467,8 @@ static const int ahc_num_pci_devs =
static struct ahc_pci_identity *ahc_find_pci_device(device_t dev);
static void check_extport(struct ahc_softc *ahc, u_int *sxfrctl1);
static void configure_termination(struct ahc_softc *ahc,
- struct seeprom_config *sc,
struct seeprom_descriptor *sd,
+ u_int adapter_control,
u_int *sxfrctl1);
static void ahc_ultra2_term_detect(struct ahc_softc *ahc,
@@ -589,7 +589,6 @@ ahc_pci_attach(device_t dev)
&regs_id, 0, ~0, 1, RF_ACTIVE);
}
#endif
-
if (regs == NULL && (command & PCI_COMMAND_IO_ENABLE) != 0) {
regs_type = SYS_RES_IOPORT;
regs_id = AHC_PCI_IOADDR;
@@ -850,8 +849,7 @@ ahc_pci_attach(device_t dev)
our_id = 0x07;
sxfrctl1 = STPWEN;
}
- ahc_outb(ahc, SCSICONF,
- (our_id & 0x07)|ENSPCHK|RESET_SCSI);
+ ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI);
ahc->our_id = our_id;
}
@@ -879,7 +877,6 @@ ahc_pci_attach(device_t dev)
}
ahc_attach(ahc);
-
return (0);
}
@@ -892,8 +889,10 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
{
struct seeprom_descriptor sd;
struct seeprom_config sc;
- u_int8_t scsi_conf;
+ u_int scsi_conf;
+ u_int adapter_control;
int have_seeprom;
+ int have_autoterm;
sd.sd_tag = ahc->tag;
sd.sd_bsh = ahc->bsh;
@@ -920,7 +919,6 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
sd.sd_DI = SEEDI;
have_seeprom = acquire_seeprom(ahc, &sd);
-
if (have_seeprom) {
if (bootverbose)
@@ -938,8 +936,8 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
/* Check checksum */
int i;
int maxaddr;
+ u_int32_t checksum;
u_int16_t *scarray;
- u_int16_t checksum;
maxaddr = (sizeof(sc)/2) - 1;
checksum = 0;
@@ -947,7 +945,8 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
for (i = 0; i < maxaddr; i++)
checksum = checksum + scarray[i];
- if (checksum == 0 || checksum != sc.checksum) {
+ if (checksum == 0
+ || (checksum & 0xFFFF) != sc.checksum) {
if (bootverbose && sd.sd_chip == C56_66)
printf ("checksum error\n");
have_seeprom = 0;
@@ -1060,24 +1059,42 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff);
}
+ /*
+ * Cards that have the external logic necessary to talk to
+ * a SEEPROM, are almost certain to have the remaining logic
+ * necessary for auto-termination control. This assumption
+ * hasn't failed yet...
+ */
+ have_autoterm = have_seeprom;
+ if (have_seeprom)
+ adapter_control = sc.adapter_control;
+ else
+ adapter_control = CFAUTOTERM;
+
+ /*
+ * Some low-cost chips have SEEPROM and auto-term control built
+ * in, instead of using a GAL. They can tell us directly
+ * if the termination logic is enabled.
+ */
if ((ahc->features & AHC_SPIOCAP) != 0) {
- if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) != 0) {
- configure_termination(ahc, &sc, &sd, sxfrctl1);
- }
- } else if (have_seeprom) {
- configure_termination(ahc, &sc, &sd, sxfrctl1);
+ if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) != 0)
+ have_autoterm = TRUE;
+ else
+ have_autoterm = FALSE;
}
+ if (have_autoterm)
+ configure_termination(ahc, &sd, adapter_control, sxfrctl1);
+
release_seeprom(&sd);
}
static void
configure_termination(struct ahc_softc *ahc,
- struct seeprom_config *sc,
struct seeprom_descriptor *sd,
+ u_int adapter_control,
u_int *sxfrctl1)
{
- int max_targ = sc->max_targets & CFMAXTARG;
u_int8_t brddat;
brddat = 0;
@@ -1094,7 +1111,7 @@ configure_termination(struct ahc_softc *ahc,
* on or we will release the seeprom.
*/
SEEPROM_OUTB(sd, sd->sd_MS | sd->sd_CS);
- if ((sc->adapter_control & CFAUTOTERM) != 0
+ if ((adapter_control & CFAUTOTERM) != 0
|| (ahc->features & AHC_ULTRA2) != 0) {
int internal50_present;
int internal68_present;
@@ -1115,14 +1132,13 @@ configure_termination(struct ahc_softc *ahc,
&enablePRI_low,
&enablePRI_high,
&eeprom_present);
- if ((sc->adapter_control & CFSEAUTOTERM) == 0) {
- enableSEC_low = (sc->adapter_control & CFSTERM);
- enableSEC_high =
- (sc->adapter_control & CFWSTERM);
+ if ((adapter_control & CFSEAUTOTERM) == 0) {
+ enableSEC_low = (adapter_control & CFSTERM);
+ enableSEC_high = (adapter_control & CFWSTERM);
}
- if ((sc->adapter_control & CFAUTOTERM) == 0) {
+ if ((adapter_control & CFAUTOTERM) == 0) {
enablePRI_low = enablePRI_high =
- (sc->adapter_control & CFLVDSTERM);
+ (adapter_control & CFLVDSTERM);
}
/* Make the table calculations below happy */
internal50_present = 0;
@@ -1139,9 +1155,8 @@ configure_termination(struct ahc_softc *ahc,
&eeprom_present);
}
- if (max_targ <= 8) {
+ if ((ahc->features & AHC_WIDE) == 0)
internal68_present = 0;
- }
if (bootverbose) {
if ((ahc->features & AHC_ULTRA2) == 0) {
@@ -1178,7 +1193,7 @@ configure_termination(struct ahc_softc *ahc,
"time!\n", ahc_name(ahc));
}
- if ((max_targ > 8)
+ if ((ahc->features & AHC_WIDE) != 0
&& ((externalcable_present == 0)
|| (internal68_present == 0)
|| (enableSEC_high != 0))) {
@@ -1221,11 +1236,8 @@ configure_termination(struct ahc_softc *ahc,
write_brdctl(ahc, brddat);
} else {
- if (sc->adapter_control & CFSTERM) {
- if ((ahc->features & AHC_ULTRA2) != 0)
- brddat |= BRDDAT5;
- else
- *sxfrctl1 |= STPWEN;
+ if ((adapter_control & CFSTERM) != 0) {
+ *sxfrctl1 |= STPWEN;
if (bootverbose)
printf("%s: %sLow byte termination Enabled\n",
@@ -1234,7 +1246,7 @@ configure_termination(struct ahc_softc *ahc,
: "");
}
- if (sc->adapter_control & CFWSTERM) {
+ if ((adapter_control & CFWSTERM) != 0) {
brddat |= BRDDAT6;
if (bootverbose)
printf("%s: %sHigh byte termination Enabled\n",
@@ -1263,7 +1275,6 @@ ahc_ultra2_term_detect(struct ahc_softc *ahc, int *enableSEC_low,
* BRDDAT3 = Enable Primary low byte termination
*/
brdctl = read_brdctl(ahc);
-
*eeprom_present = brdctl & BRDDAT7;
*enableSEC_high = (brdctl & BRDDAT6);
*enableSEC_low = (brdctl & BRDDAT5);
@@ -1374,7 +1385,7 @@ write_brdctl(ahc, value)
brdctl = BRDSTB;
if (ahc->channel == 'B')
brdctl |= BRDCS;
- } else if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7890) {
+ } else if ((ahc->features & AHC_ULTRA2) != 0) {
brdctl = 0;
} else {
brdctl = BRDSTB|BRDCS;
@@ -1382,12 +1393,12 @@ write_brdctl(ahc, value)
ahc_outb(ahc, BRDCTL, brdctl);
brdctl |= value;
ahc_outb(ahc, BRDCTL, brdctl);
- if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7890)
+ if ((ahc->features & AHC_ULTRA2) != 0)
brdctl |= BRDSTB_ULTRA2;
else
brdctl &= ~BRDSTB;
ahc_outb(ahc, BRDCTL, brdctl);
- if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7890)
+ if ((ahc->features & AHC_ULTRA2) != 0)
brdctl = 0;
else
brdctl &= ~BRDCS;
@@ -1405,7 +1416,7 @@ read_brdctl(ahc)
brdctl = BRDRW;
if (ahc->channel == 'B')
brdctl |= BRDCS;
- } else if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7890) {
+ } else if ((ahc->features & AHC_ULTRA2) != 0) {
brdctl = BRDRW_ULTRA2;
} else {
brdctl = BRDRW|BRDCS;
@@ -1634,6 +1645,7 @@ ahc_aha394XX_setup(device_t dev, char *channel, ahc_chip *chip,
printf("adapter at unexpected slot %d\n"
"unable to map to a channel\n",
pci_get_slot(dev));
+ *channel = 'A';
}
return (0);
}
@@ -1656,6 +1668,7 @@ ahc_aha398XX_setup(device_t dev, char *channel, ahc_chip *chip,
printf("adapter at unexpected slot %d\n"
"unable to map to a channel\n",
pci_get_slot(dev));
+ *channel = 'A';
}
*flags |= AHC_LARGE_SEEPROM;
return (0);