aic79xx.c:

Include read streaming in the PPR flags we display in diagnostics.

	In ahd_reset(), set the known mode after our initial pause prior to
	setting the mode. We can't just set the mode directly because the
	current mode, after the pause, is most likely unknown and setting the
	mode when the saved mode is unknown will trigger an assertion in
	the mode debug code.

	Complete an audit for SCB RAM reads.  These reads must be performed
	via the special ahd_in?_scbram() methods so we can perform a
	Rev A. PCI-X workaround.

	Remove a superfluous mode save operation that was performed just
	prior to a call to ahd_clear_critical_section().  The saved mode
	was never restored and wouldn't have been valid anyway since the
	mode could change while single stepping out of a critical section.

aic79xx.h:
	Add new BUG definition AHD_PCIX_SCBRAM_RD_BUG.

aic79xx_inline.h:
	Update ahd_inb_scbram routine to check for AHD_PCIX_SCBRAM_RD_BUG
	and only apply the workaround if this bug is active.  The old code
	applied the workaround in all cases.

aic79xx_pci.c:
	Set AHD_PCIX_SCBRAM_RD_BUG for the A4.

	Remove an attempted saved_modes call in ahd_pci_test_register_access().
	Saving the modes can only occur when we are paused, but the call was
	happening before the chip was known to be paused.  Restoring the
	modes doesn't make sense either since the code makes no assumptions
	about the state of the sequencer until the first time the mode is set
	by the driver.  This happens after the registers are successfully
	mapped.
This commit is contained in:
gibbs 2003-03-06 23:58:34 +00:00
parent 4fbc4f8ef8
commit ff18eef0a3
4 changed files with 46 additions and 38 deletions

View File

@ -37,7 +37,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.c#165 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#170 $
*
* $FreeBSD$
*/
@ -406,7 +406,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd)
u_int i;
ahd_set_scbptr(ahd, scbid);
next_scbid = ahd_inw(ahd, SCB_NEXT_COMPLETE);
next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
printf("%s: Warning - DMA-up and complete "
@ -415,7 +415,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd)
}
hscb_ptr = (uint8_t *)scb->hscb;
for (i = 0; i < sizeof(struct hardware_scb); i++)
*hscb_ptr++ = ahd_inb(ahd, SCB_BASE + i);
*hscb_ptr++ = ahd_inb_scbram(ahd, SCB_BASE + i);
ahd_complete_scb(ahd, scb);
scbid = next_scbid;
@ -426,7 +426,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd)
while (!SCBID_IS_NULL(scbid)) {
ahd_set_scbptr(ahd, scbid);
next_scbid = ahd_inw(ahd, SCB_NEXT_COMPLETE);
next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
printf("%s: Warning - Complete SCB %d invalid\n",
@ -1667,7 +1667,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
next = SCB_LIST_NULL;
} else {
ahd_set_scbptr(ahd, waiting_h);
next = ahd_inw(ahd, SCB_NEXT2);
next = ahd_inw_scbram(ahd, SCB_NEXT2);
}
ahd_set_scbptr(ahd, scbid);
ahd_outw(ahd, SCB_NEXT2, next);
@ -1998,7 +1998,8 @@ ahd_handle_proto_violation(struct ahd_softc *ahd)
if ((seq_flags & NO_CDB_SENT) != 0) {
ahd_print_path(ahd, scb);
printf("No or incomplete CDB sent to device.\n");
} else if ((ahd_inb(ahd, SCB_CONTROL) & STATUS_RCVD) == 0) {
} else if ((ahd_inb_scbram(ahd, SCB_CONTROL)
& STATUS_RCVD) == 0) {
/*
* The target never bothered to provide status to
* us prior to completing the command. Since we don't
@ -2615,8 +2616,12 @@ ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
ahd_name(ahd), devinfo->target,
period, offset);
options = 0;
if ((ppr_options & MSG_EXT_PPR_RD_STRM) != 0) {
printf("(RDSTRM");
options++;
}
if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
printf("(DT");
printf("%s", options ? "|DT" : "(DT");
options++;
}
if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
@ -4990,6 +4995,7 @@ ahd_reset(struct ahd_softc *ahd)
* to disturb the integrity of the bus.
*/
ahd_pause(ahd);
ahd_update_modes(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
sxfrctl1 = ahd_inb(ahd, SXFRCTL1);
@ -5042,10 +5048,13 @@ ahd_reset(struct ahd_softc *ahd)
/*
* Mode should be SCSI after a chip reset, but lets
* set it just to be safe.
* set it just to be safe. We touch the MODE_PTR
* register directly so as to bypass the lazy update
* code in ahd_set_modes().
*/
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
ahd_known_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
ahd_outb(ahd, MODE_PTR,
ahd_build_mode_state(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI));
/*
* Restore SXFRCTL1.
@ -7689,7 +7698,6 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
{
struct hardware_scb *hscb;
u_int qfreeze_cnt;
ahd_mode_state saved_modes;
/*
* The sequencer freezes its select-out queue
@ -7701,7 +7709,6 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
/* Freeze the queue until the client sees the error. */
ahd_pause(ahd);
saved_modes = ahd_save_modes(ahd);
ahd_clear_critical_section(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
ahd_freeze_devq(ahd, scb);

View File

@ -37,7 +37,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.h#84 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#85 $
*
* $FreeBSD$
*/
@ -258,27 +258,30 @@ typedef enum {
AHD_PCIX_CHIPRST_BUG = 0x0040,
/* MMAPIO is not functional in PCI-X mode. */
AHD_PCIX_MMAPIO_BUG = 0x0080,
/* Reads to SCBRAM fail to reset the discard timer. */
AHD_PCIX_SCBRAM_RD_BUG = 0x0100,
/* Bug workarounds that can be disabled on non-PCIX busses. */
AHD_PCIX_BUG_MASK = AHD_PCIX_CHIPRST_BUG
| AHD_PCIX_MMAPIO_BUG,
| AHD_PCIX_MMAPIO_BUG
| AHD_PCIX_SCBRAM_RD_BUG,
/*
* LQOSTOP0 status set even for forced selections with ATN
* to perform non-packetized message delivery.
*/
AHD_LQO_ATNO_BUG = 0x0100,
AHD_LQO_ATNO_BUG = 0x0200,
/* FIFO auto-flush does not always trigger. */
AHD_AUTOFLUSH_BUG = 0x0200,
AHD_AUTOFLUSH_BUG = 0x0400,
/* The CLRLQO registers are not self-clearing. */
AHD_CLRLQO_AUTOCLR_BUG = 0x0400,
AHD_CLRLQO_AUTOCLR_BUG = 0x0800,
/* The PACKETIZED status bit refers to the previous connection. */
AHD_PKTIZED_STATUS_BUG = 0x0800,
AHD_PKTIZED_STATUS_BUG = 0x1000,
/* "Short Luns" are not placed into outgoing LQ packets correctly. */
AHD_PKT_LUN_BUG = 0x1000,
AHD_PKT_LUN_BUG = 0x2000,
/*
* Only the FIFO allocated to the non-packetized connection may
* be in use during a non-packetzied connection.
*/
AHD_NONPACKFIFO_BUG = 0x2000,
AHD_NONPACKFIFO_BUG = 0x4000,
/*
* Writing to a DFF SCBPTR register may fail if concurent with
* a hardware write to the other DFF SCBPTR register. This is
@ -286,30 +289,30 @@ typedef enum {
* this bug have the AHD_NONPACKFIFO_BUG and all writes of concern
* occur in non-packetized connections.
*/
AHD_MDFF_WSCBPTR_BUG = 0x4000,
AHD_MDFF_WSCBPTR_BUG = 0x8000,
/* SGHADDR updates are slow. */
AHD_REG_SLOW_SETTLE_BUG = 0x8000,
AHD_REG_SLOW_SETTLE_BUG = 0x10000,
/*
* Changing the MODE_PTR coincident with an interrupt that
* switches to a different mode will cause the interrupt to
* be in the mode written outside of interrupt context.
*/
AHD_SET_MODE_BUG = 0x10000,
AHD_SET_MODE_BUG = 0x20000,
/* Non-packetized busfree revision does not work. */
AHD_BUSFREEREV_BUG = 0x20000,
AHD_BUSFREEREV_BUG = 0x40000,
/*
* Paced transfers are indicated with a non-standard PPR
* option bit in the neg table, 160MHz is indicated by
* sync factor 0x7, and the offset if off by a factor of 2.
*/
AHD_PACED_NEGTABLE_BUG = 0x40000,
AHD_PACED_NEGTABLE_BUG = 0x80000,
/* LQOOVERRUN false positives. */
AHD_LQOOVERRUN_BUG = 0x80000,
AHD_LQOOVERRUN_BUG = 0x100000,
/*
* Controller write to INTSTAT will lose to a host
* write to CLRINT.
*/
AHD_INTCOLLISION_BUG = 0x100000,
AHD_INTCOLLISION_BUG = 0x200000,
/*
* The GEM318 violates the SCSI spec by not waiting
* the mandated bus settle delay between phase changes
@ -319,7 +322,7 @@ typedef enum {
* glitches. This flag tells the firmware to tolerate
* early REQ assertions.
*/
AHD_EARLY_REQ_BUG = 0x200000
AHD_EARLY_REQ_BUG = 0x400000
} ahd_bug;
/*

View File

@ -37,7 +37,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_inline.h#43 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#44 $
*
* $FreeBSD$
*/
@ -678,7 +678,8 @@ ahd_inb_scbram(struct ahd_softc *ahd, u_int offset)
* Razor #528
*/
value = ahd_inb(ahd, offset);
ahd_inb(ahd, MODE_PTR);
if ((ahd->flags & AHD_PCIX_SCBRAM_RD_BUG) != 0)
ahd_inb(ahd, MODE_PTR);
return (value);
}

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#66 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#67 $
*
* $FreeBSD$
*/
@ -385,12 +385,10 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
int
ahd_pci_test_register_access(struct ahd_softc *ahd)
{
ahd_mode_state saved_modes;
uint32_t cmd;
int error;
uint8_t hcntrl;
saved_modes = ahd_save_modes(ahd);
error = EIO;
/*
@ -456,7 +454,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
ahd_outb(ahd, CLRINT, CLRPCIINT);
}
ahd_restore_modes(ahd, saved_modes);
ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
return (error);
@ -886,11 +883,11 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
| AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
| AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
| AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
| AHD_PCIX_CHIPRST_BUG|AHD_PKTIZED_STATUS_BUG
| AHD_PKT_LUN_BUG|AHD_MDFF_WSCBPTR_BUG
| AHD_REG_SLOW_SETTLE_BUG|AHD_SET_MODE_BUG
| AHD_BUSFREEREV_BUG|AHD_NONPACKFIFO_BUG
| AHD_PACED_NEGTABLE_BUG;
| AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
| AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
| AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
| AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
| AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG;
/*
* IO Cell paramter setup.