aboutsummaryrefslogtreecommitdiff
path: root/sys
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
parentc2af6f650c4eb0f16a2f41bc527c7d2a85b45039 (diff)
downloadsrc-820379186bbe4943772455044e62b1f80aea6e4b.tar.gz
src-820379186bbe4943772455044e62b1f80aea6e4b.zip
Simplify my license.
Don't arbitrarily limit the initiator ID of the card to something <= 7. Fix a bug in the checksum code that would incorrectly prevent a valid checksum of zero. (cp) Don't touch rely on seeprom data when configuring termination. We may not have seeprom data. (cp) Treat all ULTRA2 capable adapters the same way when reading or writing the BRDCTL register. We previously only did this correctly for aic7890/91 chips. This should correct some problems with termination settings on aic7896/97 adapters. (cp) Changes marked with "(cp)" Pointed out by: Chuck Paterson <cp@bsdi.com>
Notes
Notes: svn path=/head/; revision=54213
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/aic7xxx/ahc_pci.c91
-rw-r--r--sys/pci/ahc_pci.c91
2 files changed, 104 insertions, 78 deletions
diff --git a/sys/dev/aic7xxx/ahc_pci.c b/sys/dev/aic7xxx/ahc_pci.c
index fd91f5e1a0dc..78a6ce4259d4 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);
diff --git a/sys/pci/ahc_pci.c b/sys/pci/ahc_pci.c
index fd91f5e1a0dc..78a6ce4259d4 100644
--- a/sys/pci/ahc_pci.c
+++ b/sys/pci/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);