Last minute fixes to ahc and ahd:

ahd_pci.c:
	Retrieve the allow_memio hint from the resource manager to
	determine whether or not to try PCI MEMIO.

aic79xx_osm.h:
aic7xxx_osm.h:
	Don't wrongly abuse the callout_reset() interface when trying
	to abuse timeouts generated from the CAM layer.  This fixes the
	console freeze and lost timeout problem that many have reported,
	especially on SMP systems.

aic79xx_pci.c
aic7xxx_pci.c
	Rewrite the MEMIO test routine to prevent certain broken chipsets
	from trying to burst multiple DWORDs to the registers.  Also make
	the routine better detect byte merging by the host bridge and
	deal with it.

aic79xx.reg:
	Correct an incorrect register definition.

Approved by:	re (rwatson, jhb)
This commit is contained in:
Scott Long 2002-12-04 22:51:29 +00:00
parent e7cba1c7dd
commit 97cae63d7f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=107623
6 changed files with 95 additions and 48 deletions

View file

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#9 $
* $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#10 $
*
* $FreeBSD$
*/
@ -150,14 +150,26 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
int regs_type;
int regs_id;
int regs_id2;
int allow_memio;
command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1);
regs = NULL;
regs2 = NULL;
regs_type = 0;
regs_id = 0;
/* Retrieve the per-device 'allow_memio' hint */
if (resource_int_value(device_get_name(ahd->dev_softc),
device_get_unit(ahd->dev_softc),
"allow_memio", &allow_memio) != 0) {
if (bootverbose)
device_printf(ahd->dev_softc,
"Defaulting to MEMIO on\n");
}
if ((command & PCIM_CMD_MEMEN) != 0
&& (ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0) {
&& (ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0
&& allow_memio != 0) {
regs_type = SYS_RES_MEMORY;
regs_id = AHD_PCI_MEMADDR;

View file

@ -39,7 +39,7 @@
*
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#55 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#56 $"
/*
* This file is processed by the aic7xxx_asm utility for use in assembling
@ -190,6 +190,7 @@ register CLRINT {
field CLRHWERRINT 0x80 /* Rev B or greater */
field CLRBRKADRINT 0x40
field CLRSWTMINT 0x20
field CLRPCIINT 0x10
field CLRSCSIINT 0x08
field CLRSEQINT 0x04
field CLRCMDINT 0x02
@ -1168,7 +1169,7 @@ register MSIPCISTAT {
* PCI Status for Target
*/
register TARGPCISTAT {
address 0x0A6
address 0x0A7
access_mode RW
modes M_CFG
field DPE 0x80

View file

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#18 $
* $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#19 $
*
* $FreeBSD$
*/
@ -239,8 +239,9 @@ ahd_timer_reset(ahd_timer_t *timer, u_int usec, ahd_callback_t *func, void *arg)
static __inline void
ahd_scb_timer_reset(struct scb *scb, u_int usec)
{
callout_reset(scb->io_ctx->ccb_h.timeout_ch.callout,
(usec * hz)/1000000, ahd_timeout, scb);
untimeout(ahd_timeout, (caddr_t)scb, scb->io_ctx->ccb_h.timeout_ch);
scb->io_ctx->ccb_h.timeout_ch =
timeout(ahd_timeout, scb, (usec * hz)/1000000);
}
/*************************** Device Access ************************************/

View file

@ -38,7 +38,7 @@
* 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#54 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#60 $
*
* $FreeBSD$
*/
@ -175,8 +175,8 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
},
/* Generic chip probes for devices we don't know 'exactly' */
{
ID_AIC7901A & ID_ALL_MASK,
ID_ALL_MASK,
ID_AIC7901A & ID_DEV_VENDOR_MASK,
ID_DEV_VENDOR_MASK,
"Adaptec AIC7901A Ultra320 SCSI adapter",
ahd_aic7901A_setup
},
@ -378,7 +378,16 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
int
ahd_pci_test_register_access(struct ahd_softc *ahd)
{
int i;
ahd_mode_state saved_modes;
int error;
uint8_t seqctl;
saved_modes = ahd_save_modes(ahd);
error = EIO;
/* Enable PCI error interrupt status */
seqctl = ahd_inb(ahd, SEQCTL0);
ahd_outb(ahd, SEQCTL0, seqctl & ~FAILDIS);
/*
* First a simple test to see if any
@ -389,7 +398,7 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
* use for this test.
*/
if (ahd_inb(ahd, HCNTRL) == 0xFF)
return (EIO);
goto fail;
/*
* Next create a situation where write combining
@ -398,19 +407,26 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
* either, so look for data corruption and/or flaged
* PCI errors.
*/
for (i = 0; i < 16; i++)
ahd_outb(ahd, SRAM_BASE + i, i);
for (i = 0; i < 16; i++)
if (ahd_inb(ahd, SRAM_BASE + i) != i)
return (EIO);
ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
goto fail;
if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
ahd_mode_state saved_modes;
u_int targpcistat;
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
targpcistat = ahd_inb(ahd, TARGPCISTAT);
if ((targpcistat & STA) != 0)
goto fail;
}
error = 0;
fail:
if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
u_int targpcistat;
u_int pci_status1;
saved_modes = ahd_save_modes(ahd);
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
targpcistat = ahd_inb(ahd, TARGPCISTAT);
@ -420,13 +436,12 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
PCIR_STATUS + 1, /*bytes*/1);
ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
pci_status1, /*bytes*/1);
ahd_restore_modes(ahd, saved_modes);
if ((targpcistat & STA) != 0)
return (EIO);
ahd_outb(ahd, CLRINT, CLRPCIINT);
}
return (0);
ahd_restore_modes(ahd, saved_modes);
ahd_outb(ahd, SEQCTL0, seqctl);
return (error);
}
/*
@ -731,7 +746,7 @@ ahd_pci_intr(struct ahd_softc *ahd)
s = pci_status_strings[bit];
if (i == 7/*TARG*/ && bit == 3)
s = "%s: Signal Target Abort\n";
s = "%s: Signaled Target Abort\n";
printf(s, ahd_name(ahd), pci_status_source[i]);
}
}
@ -741,6 +756,7 @@ ahd_pci_intr(struct ahd_softc *ahd)
ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
pci_status1, /*bytes*/1);
ahd_restore_modes(ahd, saved_modes);
ahd_outb(ahd, CLRINT, CLRPCIINT);
ahd_unpause(ahd);
}
@ -810,6 +826,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
*/
ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
pcix_status, /*bytes*/2);
ahd_outb(ahd, CLRINT, CLRSPLTINT);
ahd_restore_modes(ahd, saved_modes);
}

View file

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#13 $
* $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#14 $
*
* $FreeBSD$
*/
@ -251,8 +251,9 @@ ahc_timer_reset(ahc_timer_t *timer, u_int usec, ahc_callback_t *func, void *arg)
static __inline void
ahc_scb_timer_reset(struct scb *scb, u_int usec)
{
callout_reset(scb->io_ctx->ccb_h.timeout_ch.callout,
(usec * hz)/1000000, ahc_timeout, scb);
untimeout(ahc_timeout, (caddr_t)scb, scb->io_ctx->ccb_h.timeout_ch);
scb->io_ctx->ccb_h.timeout_ch =
timeout(ahc_timeout, scb, (usec * hz)/1000000);
}
/*************************** Device Access ************************************/

View file

@ -39,7 +39,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#52 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#53 $
*
* $FreeBSD$
*/
@ -1202,8 +1202,15 @@ ahc_probe_ext_scbram(struct ahc_softc *ahc)
int
ahc_pci_test_register_access(struct ahc_softc *ahc)
{
int i;
int error;
u_int status1;
uint8_t seqctl;
error = EIO;
/* Enable PCI error interrupt status */
seqctl = ahc_inb(ahc, SEQCTL);
ahc_outb(ahc, SEQCTL, seqctl & ~FAILDIS);
/*
* First a simple test to see if any
@ -1214,7 +1221,7 @@ ahc_pci_test_register_access(struct ahc_softc *ahc)
* use for this test.
*/
if (ahc_inb(ahc, HCNTRL) == 0xFF)
return (EIO);
goto fail;
/*
* Next create a situation where write combining
@ -1223,25 +1230,33 @@ ahc_pci_test_register_access(struct ahc_softc *ahc)
* either, so look for data corruption and/or flagged
* PCI errors.
*/
for (i = 0; i < 16; i++)
ahc_outb(ahc, SRAM_BASE + i, i);
ahc_outb(ahc, SRAM_BASE, 0xaa);
ahc_outb(ahc, SRAM_BASE + 1, 0x55);
ahc_outb(ahc, SRAM_BASE + 2, 0xa5);
ahc_outb(ahc, SRAM_BASE + 3, 0x5a);
for (i = 0; i < 16; i++)
if (ahc_inb(ahc, SRAM_BASE + i) != i)
return (EIO);
if ((ahc_inb(ahc, SRAM_BASE) != 0xaa)
|| (ahc_inb(ahc, SRAM_BASE + 1) != 0x55)
|| (ahc_inb(ahc, SRAM_BASE + 2) != 0xa5)
|| (ahc_inb(ahc, SRAM_BASE + 3) != 0x5a))
goto fail;
status1 = ahc_pci_read_config(ahc->dev_softc,
PCIR_STATUS + 1, /*bytes*/1);
if ((status1 & STA) != 0) {
if ((status1 & STA) != 0)
goto fail;
error = 0;
fail:
/* Silently clear any latched errors. */
status1 = ahc_pci_read_config(ahc->dev_softc,
PCIR_STATUS + 1, /*bytes*/1);
ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
status1, /*bytes*/1);
ahc_outb(ahc, CLRINT, CLRPARERR);
return (EIO);
}
return (0);
ahc_outb(ahc, SEQCTL, seqctl);
return (error);
}
/*