/* * Product specific probe and attach routines for: * aic7901 and aic7902 SCSI controllers * * Copyright (c) 1994-2001 Justin T. Gibbs. * Copyright (c) 2000-2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#92 $
*/
/* * Controllers, mask out the IROC/HostRAID bit
*/
full_id &= ID_ALL_IROC_MASK;
for (i = 0; i < ahd_num_pci_devs; i++) {
entry = &ahd_pci_ident_table[i]; if (entry->full_id == (full_id & entry->id_mask)) { /* Honor exclusion entries. */ if (entry->name == NULL) return (NULL); return (entry);
}
} return (NULL);
}
int
ahd_pci_config(struct ahd_softc *ahd, conststruct ahd_pci_identity *entry)
{
u_int command;
uint32_t devconfig;
uint16_t subvendor; int error;
ahd->description = entry->name; /* * Record if this is an HP board.
*/
subvendor = ahd_pci_read_config(ahd->dev_softc,
PCI_SUBSYSTEM_VENDOR_ID, /*bytes*/2); if (subvendor == SUBID_HP)
ahd->flags |= AHD_HP_BOARD;
error = entry->setup(ahd); if (error != 0) return (error);
error = ahd_pci_map_registers(ahd); if (error != 0) return (error);
/* * If we need to support high memory, enable dual * address cycles. This bit must be set to enable * high address bit generation even if we are on a * 64bit bus (PCI64BIT set in devconfig).
*/ if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) { if (bootverbose)
printk("%s: Enabling 39Bit Addressing\n",
ahd_name(ahd));
devconfig = ahd_pci_read_config(ahd->dev_softc,
DEVCONFIG, /*bytes*/4);
devconfig |= DACEN;
ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
devconfig, /*bytes*/4);
}
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); /* See if we have a SEEPROM and perform auto-term */
error = ahd_check_extport(ahd); if (error != 0) return (error);
/* * Perform some simple tests that should catch situations where * our registers are invalidly mapped.
*/ int
ahd_pci_test_register_access(struct ahd_softc *ahd)
{
uint32_t cmd;
u_int targpcistat;
u_int pci_status1; int error;
uint8_t hcntrl;
error = EIO;
/* * Enable PCI error interrupt status, but suppress NMIs * generated by SERR raised due to target aborts.
*/
cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
/* * First a simple test to see if any * registers can be read. Reading * HCNTRL has no side effects and has * at least one bit that is guaranteed to * be zero so it is a good register to * use for this test.
*/
hcntrl = ahd_inb(ahd, HCNTRL); if (hcntrl == 0xFF) goto fail;
/* * Next create a situation where write combining * or read prefetching could be initiated by the * CPU or host bridge. Our device does not support * either, so look for data corruption and/or flaged * PCI errors. First pause without causing another * chip reset.
*/
hcntrl &= ~CHIPRST;
ahd_outb(ahd, HCNTRL, hcntrl|PAUSE); while (ahd_is_paused(ahd) == 0)
;
/* * Check the external port logic for a serial eeprom * and termination/cable detection contrls.
*/ staticint
ahd_check_extport(struct ahd_softc *ahd)
{ struct vpd_config vpd; struct seeprom_config *sc;
u_int adapter_control; int have_seeprom; int error;
/* Make sure current sensing is off. */ if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
(void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
}
/* * Now set the termination based on what we found.
*/
sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
ahd->flags &= ~AHD_TERM_ENB_A; if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
ahd->flags |= AHD_TERM_ENB_A;
sxfrctl1 |= STPWEN;
} /* Must set the latch once in order to be effective. */
ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
ahd_outb(ahd, SXFRCTL1, sxfrctl1);
error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl); if (error != 0) {
printk("%s: Unable to set termination settings!\n",
ahd_name(ahd));
} elseif (bootverbose) {
printk("%s: Primary High byte termination %sabled\n",
ahd_name(ahd),
(termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
staticconstchar *split_status_strings[] =
{ "%s: Received split response in %s.\n", "%s: Received split completion error message in %s\n", "%s: Receive overrun in %s\n", "%s: Count not complete in %s\n", "%s: Split completion data bucket in %s\n", "%s: Split completion address error in %s\n", "%s: Split completion byte count error in %s\n", "%s: Signaled Target-abort to early terminate a split in %s\n"
};
staticconstchar *pci_status_strings[] =
{ "%s: Data Parity Error has been reported via PERR# in %s\n", "%s: Target initial wait state error in %s\n", "%s: Split completion read data parity error in %s\n", "%s: Split completion address attribute parity error in %s\n", "%s: Received a Target Abort in %s\n", "%s: Received a Master Abort in %s\n", "%s: Signal System Error Detected in %s\n", "%s: Address or Write Phase Parity Error Detected in %s.\n"
};
/* * Check for splits in all modes. Modes 0 and 1 * additionally have SG engine splits to look at.
*/
pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS, /*bytes*/2);
printk("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
ahd_name(ahd), pcix_status);
saved_modes = ahd_save_modes(ahd); for (i = 0; i < 4; i++) {
ahd_set_modes(ahd, i, i);
if ((ahd->flags & AHD_HP_BOARD) == 0)
AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
} else { /* This is revision B and newer. */ extern uint32_t aic79xx_slowcrc;
u_int devconfig1;
/* * Set the PREQDIS bit for H2B which disables some workaround * that doesn't work on regular PCI busses. * XXX - Find out exactly what this does from the hardware * folks!
*/
devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
ahd_pci_write_config(pci, DEVCONFIG1,
devconfig1|PREQDIS, /*bytes*/1);
devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
}
return (0);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.