1998-09-15 07:24:17 +00:00
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* Core definitions and data structures shareable across OS platforms.
|
1998-09-15 07:24:17 +00:00
|
|
|
*
|
2001-01-27 20:54:24 +00:00
|
|
|
* Copyright (c) 1994-2001 Justin T. Gibbs.
|
2002-04-24 16:58:51 +00:00
|
|
|
* Copyright (c) 2000-2001 Adaptec Inc.
|
1998-09-15 07:24:17 +00:00
|
|
|
* 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,
|
1999-12-06 18:23:31 +00:00
|
|
|
* without modification.
|
2002-04-24 16:58:51 +00:00
|
|
|
* 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.
|
1998-09-15 07:24:17 +00:00
|
|
|
*
|
1999-12-06 18:23:31 +00:00
|
|
|
* Alternatively, this software may be distributed under the terms of the
|
2002-04-24 16:58:51 +00:00
|
|
|
* GNU General Public License ("GPL") version 2 as published by the Free
|
|
|
|
* Software Foundation.
|
1998-09-15 07:24:17 +00:00
|
|
|
*
|
2002-04-24 16:58:51 +00:00
|
|
|
* 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
|
1998-09-15 07:24:17 +00:00
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
2002-04-24 16:58:51 +00:00
|
|
|
* 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.
|
1998-09-15 07:24:17 +00:00
|
|
|
*
|
2002-08-31 06:42:10 +00:00
|
|
|
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#51 $
|
2000-09-16 20:02:28 +00:00
|
|
|
*
|
1999-08-28 01:08:13 +00:00
|
|
|
* $FreeBSD$
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _AIC7XXX_H_
|
|
|
|
#define _AIC7XXX_H_
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/* Register Definitions */
|
2000-07-18 20:12:14 +00:00
|
|
|
#include "aic7xxx_reg.h"
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/************************* Forward Declarations *******************************/
|
|
|
|
struct ahc_platform_data;
|
|
|
|
struct scb_platform_data;
|
2002-04-24 16:58:51 +00:00
|
|
|
struct seeprom_descriptor;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/****************************** Useful Macros *********************************/
|
1999-04-23 23:27:31 +00:00
|
|
|
#ifndef MAX
|
|
|
|
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MIN
|
|
|
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
|
|
#endif
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
#ifndef TRUE
|
|
|
|
#define TRUE 1
|
|
|
|
#endif
|
|
|
|
#ifndef FALSE
|
|
|
|
#define FALSE 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array))
|
|
|
|
|
|
|
|
#define ALL_CHANNELS '\0'
|
|
|
|
#define ALL_TARGETS_MASK 0xFFFF
|
|
|
|
#define INITIATOR_WILDCARD (~0)
|
|
|
|
|
|
|
|
#define SCSIID_TARGET(ahc, scsiid) \
|
|
|
|
(((scsiid) & ((((ahc)->features & AHC_TWIN) != 0) ? TWIN_TID : TID)) \
|
|
|
|
>> TID_SHIFT)
|
|
|
|
#define SCSIID_OUR_ID(scsiid) \
|
|
|
|
((scsiid) & OID)
|
|
|
|
#define SCSIID_CHANNEL(ahc, scsiid) \
|
|
|
|
((((ahc)->features & AHC_TWIN) != 0) \
|
|
|
|
? ((((scsiid) & TWIN_CHNLB) != 0) ? 'B' : 'A') \
|
|
|
|
: 'A')
|
|
|
|
#define SCB_IS_SCSIBUS_B(ahc, scb) \
|
|
|
|
(SCSIID_CHANNEL(ahc, (scb)->hscb->scsiid) == 'B')
|
|
|
|
#define SCB_GET_OUR_ID(scb) \
|
|
|
|
SCSIID_OUR_ID((scb)->hscb->scsiid)
|
|
|
|
#define SCB_GET_TARGET(ahc, scb) \
|
|
|
|
SCSIID_TARGET((ahc), (scb)->hscb->scsiid)
|
|
|
|
#define SCB_GET_CHANNEL(ahc, scb) \
|
|
|
|
SCSIID_CHANNEL(ahc, (scb)->hscb->scsiid)
|
|
|
|
#define SCB_GET_LUN(scb) \
|
|
|
|
((scb)->hscb->lun)
|
|
|
|
#define SCB_GET_TARGET_OFFSET(ahc, scb) \
|
|
|
|
(SCB_GET_TARGET(ahc, scb) + (SCB_IS_SCSIBUS_B(ahc, scb) ? 8 : 0))
|
|
|
|
#define SCB_GET_TARGET_MASK(ahc, scb) \
|
|
|
|
(0x01 << (SCB_GET_TARGET_OFFSET(ahc, scb)))
|
|
|
|
#define TCL_TARGET_OFFSET(tcl) \
|
|
|
|
((((tcl) >> 4) & TID) >> 4)
|
|
|
|
#define TCL_LUN(tcl) \
|
|
|
|
(tcl & (AHC_NUM_LUNS - 1))
|
|
|
|
#define BUILD_TCL(scsiid, lun) \
|
|
|
|
((lun) | (((scsiid) & TID) << 4))
|
|
|
|
|
Sync Perforce IDs, add tranceiver state change support, and correct
numerous error recovery buglets.
Many thanks to Tor Egge for his assistance in diagnosing problems with
the error recovery code.
aic7xxx.c:
Report missed bus free events using their own sequencer interrupt
code to avoid confusion with other "bad phase" interrupts.
Remove a delay used in debugging. This delay could only be hit
in certain, very extreme, error recovery scenarios.
Handle transceiver state changes correctly. You can now
plug an SE device into a hot-plug LVD bus without hanging
the controller.
When stepping through a critical section, panic if we step
more than a reasonable number of times.
After a bus reset, disable bus reset interupts until we either
our first attempt to (re)select another device, or another device
attemps to select us. This removes the need to busy wait in
kernel for the scsi reset line to fall yet still ensures we
see any reset events that impact the state of either our initiator
or target roles. Before this change, we had the potential of
servicing a "storm" of reset interrupts if the reset line was
held for a significant amount of time.
Indicate the current sequencer address whenever we dump the
card's state.
aic7xxx.reg:
Transceiver state change register definitions.
Add the missed bussfree sequencer interrupt code.
Re-enable the scsi reset interrupt if it has been
disabled before every attempt to (re)select a device
and when we have been selected as a target.
When being (re)selected, check to see if the selection
dissappeared just after we enabled our bus free interrupt.
If the bus has gone free again, go back to the idle loop
and wait for another selection.
Note two locations where we should change our behavior
if ATN is still raised. If ATN is raised during the
presentation of a command complete or disconnect message,
we should ignore the message and expect the target to put
us in msgout phase. We don't currently do this as it
requires some code re-arrangement so that critical sections
can be properly placed around our handling of these two
events. Otherwise, we cannot guarantee that the check of
ATN is atomic relative to our acking of the message in
byte (the kernel could assert ATN).
Only set the IDENTIFY_SEEN flag after we have settled
on the SCB for this transaction. The kernel looks at
this flag before assuming that SCB_TAG is valid. This
avoids confusion during certain types of error recovery.
Add a critical section around findSCB. We cannot allow
the kernel to remove an entry from the disconnected
list while we are traversing it. Ditto for get_free_or_disc_scb.
aic7xxx_freebsd.c:
Only assume that SCB_TAG is accurate if IDENTIFY_SEEN is
set in SEQ_FLAGS.
Fix a typo that caused us to execute some code for the
non-SCB paging case when paging SCBs. This only occurred
during error recovery.
2000-11-10 20:13:41 +00:00
|
|
|
#ifndef AHC_TARGET_MODE
|
|
|
|
#undef AHC_TMODE_ENABLE
|
|
|
|
#define AHC_TMODE_ENABLE 0
|
|
|
|
#endif
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/**************************** Driver Constants ********************************/
|
2000-07-18 20:12:14 +00:00
|
|
|
/*
|
|
|
|
* The maximum number of supported targets.
|
|
|
|
*/
|
|
|
|
#define AHC_NUM_TARGETS 16
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The maximum number of supported luns.
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
* The identify message only supports 64 luns in SPI3.
|
|
|
|
* You can have 2^64 luns when information unit transfers are enabled,
|
|
|
|
* but it is doubtful this driver will ever support IUTs.
|
2000-07-18 20:12:14 +00:00
|
|
|
*/
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
#define AHC_NUM_LUNS 64
|
2000-07-18 20:12:14 +00:00
|
|
|
|
1999-04-23 23:27:31 +00:00
|
|
|
/*
|
|
|
|
* The maximum transfer per S/G segment.
|
|
|
|
*/
|
1998-09-15 07:24:17 +00:00
|
|
|
#define AHC_MAXTRANSFER_SIZE 0x00ffffff /* limited by 24bit counter */
|
1999-04-23 23:27:31 +00:00
|
|
|
|
2001-01-22 21:03:48 +00:00
|
|
|
/*
|
|
|
|
* The maximum amount of SCB storage in hardware on a controller.
|
|
|
|
* This value represents an upper bound. Controllers vary in the number
|
|
|
|
* they actually support.
|
|
|
|
*/
|
|
|
|
#define AHC_SCB_MAX 255
|
|
|
|
|
1999-04-23 23:27:31 +00:00
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* The maximum number of concurrent transactions supported per driver instance.
|
|
|
|
* Sequencer Control Blocks (SCBs) store per-transaction information. Although
|
|
|
|
* the space for SCBs on the host adapter varies by model, the driver will
|
|
|
|
* page the SCBs between host and controller memory as needed. We are limited
|
2001-01-22 21:03:48 +00:00
|
|
|
* to 253 because:
|
|
|
|
* 1) The 8bit nature of the RISC engine holds us to an 8bit value.
|
|
|
|
* 2) We reserve one value, 255, to represent the invalid element.
|
|
|
|
* 3) Our input queue scheme requires one SCB to always be reserved
|
|
|
|
* in advance of queuing any SCBs. This takes us down to 254.
|
|
|
|
* 4) To handle our output queue correctly on machines that only
|
|
|
|
* support 32bit stores, we must clear the array 4 bytes at a
|
|
|
|
* time. To avoid colliding with a DMA write from the sequencer,
|
|
|
|
* we must be sure that 4 slots are empty when we write to clear
|
|
|
|
* the queue. This reduces us to 253 SCBs: 1 that just completed
|
|
|
|
* and the known three additional empty slots in the queue that
|
2001-02-18 10:25:42 +00:00
|
|
|
* precede it.
|
2000-09-16 20:02:28 +00:00
|
|
|
*/
|
2001-01-22 21:03:48 +00:00
|
|
|
#define AHC_MAX_QUEUE 253
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2002-04-24 16:58:51 +00:00
|
|
|
/*
|
|
|
|
* The maximum amount of SCB storage we allocate in host memory. This
|
|
|
|
* number should reflect the 1 additional SCB we require to handle our
|
|
|
|
* qinfifo mechanism.
|
|
|
|
*/
|
|
|
|
#define AHC_SCB_MAX_ALLOC (AHC_MAX_QUEUE+1)
|
|
|
|
|
2000-07-18 20:12:14 +00:00
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* Ring Buffer of incoming target commands.
|
|
|
|
* We allocate 256 to simplify the logic in the sequencer
|
|
|
|
* by using the natural wrap point of an 8bit counter.
|
2000-07-18 20:12:14 +00:00
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
#define AHC_TMODE_CMDS 256
|
|
|
|
|
|
|
|
/* Reset line assertion time in us */
|
2002-08-31 06:42:10 +00:00
|
|
|
#define AHC_BUSRESET_DELAY 25
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/******************* Chip Characteristics/Operating Settings *****************/
|
|
|
|
/*
|
|
|
|
* Chip Type
|
|
|
|
* The chip order is from least sophisticated to most sophisticated.
|
|
|
|
*/
|
1998-09-15 07:24:17 +00:00
|
|
|
typedef enum {
|
|
|
|
AHC_NONE = 0x0000,
|
|
|
|
AHC_CHIPID_MASK = 0x00FF,
|
|
|
|
AHC_AIC7770 = 0x0001,
|
|
|
|
AHC_AIC7850 = 0x0002,
|
1999-08-30 16:12:39 +00:00
|
|
|
AHC_AIC7855 = 0x0003,
|
|
|
|
AHC_AIC7859 = 0x0004,
|
|
|
|
AHC_AIC7860 = 0x0005,
|
|
|
|
AHC_AIC7870 = 0x0006,
|
|
|
|
AHC_AIC7880 = 0x0007,
|
2000-07-18 20:12:14 +00:00
|
|
|
AHC_AIC7895 = 0x0008,
|
2000-09-16 20:02:28 +00:00
|
|
|
AHC_AIC7895C = 0x0009,
|
|
|
|
AHC_AIC7890 = 0x000a,
|
|
|
|
AHC_AIC7896 = 0x000b,
|
|
|
|
AHC_AIC7892 = 0x000c,
|
|
|
|
AHC_AIC7899 = 0x000d,
|
1998-09-15 07:24:17 +00:00
|
|
|
AHC_VL = 0x0100, /* Bus type VL */
|
|
|
|
AHC_EISA = 0x0200, /* Bus type EISA */
|
|
|
|
AHC_PCI = 0x0400, /* Bus type PCI */
|
1999-12-06 18:23:31 +00:00
|
|
|
AHC_BUS_MASK = 0x0F00
|
1998-09-15 07:24:17 +00:00
|
|
|
} ahc_chip;
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Features available in each chip type.
|
|
|
|
*/
|
1998-09-15 07:24:17 +00:00
|
|
|
typedef enum {
|
2000-09-16 20:02:28 +00:00
|
|
|
AHC_FENONE = 0x00000,
|
|
|
|
AHC_ULTRA = 0x00001, /* Supports 20MHz Transfers */
|
|
|
|
AHC_ULTRA2 = 0x00002, /* Supports 40MHz Transfers */
|
|
|
|
AHC_WIDE = 0x00004, /* Wide Channel */
|
|
|
|
AHC_TWIN = 0x00008, /* Twin Channel */
|
|
|
|
AHC_MORE_SRAM = 0x00010, /* 80 bytes instead of 64 */
|
|
|
|
AHC_CMD_CHAN = 0x00020, /* Has a Command DMA Channel */
|
|
|
|
AHC_QUEUE_REGS = 0x00040, /* Has Queue management registers */
|
|
|
|
AHC_SG_PRELOAD = 0x00080, /* Can perform auto-SG preload */
|
|
|
|
AHC_SPIOCAP = 0x00100, /* Has a Serial Port I/O Cap Register */
|
|
|
|
AHC_MULTI_TID = 0x00200, /* Has bitmask of TIDs for select-in */
|
|
|
|
AHC_HS_MAILBOX = 0x00400, /* Has HS_MAILBOX register */
|
|
|
|
AHC_DT = 0x00800, /* Double Transition transfers */
|
|
|
|
AHC_NEW_TERMCTL = 0x01000, /* Newer termination scheme */
|
|
|
|
AHC_MULTI_FUNC = 0x02000, /* Multi-Function Twin Channel Device */
|
|
|
|
AHC_LARGE_SCBS = 0x04000, /* 64byte SCBs */
|
|
|
|
AHC_AUTORATE = 0x08000, /* Automatic update of SCSIRATE/OFFSET*/
|
|
|
|
AHC_AUTOPAUSE = 0x10000, /* Automatic pause on register access */
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
AHC_TARGETMODE = 0x20000, /* Has tested target mode support */
|
|
|
|
AHC_MULTIROLE = 0x40000, /* Space for two roles at a time */
|
2001-01-22 21:03:48 +00:00
|
|
|
AHC_REMOVABLE = 0x80000, /* Hot-Swap supported */
|
2000-07-18 20:12:14 +00:00
|
|
|
AHC_AIC7770_FE = AHC_FENONE,
|
2001-05-15 19:41:12 +00:00
|
|
|
/*
|
|
|
|
* The real 7850 does not support Ultra modes, but there are
|
|
|
|
* several cards that use the generic 7850 PCI ID even though
|
|
|
|
* they are using an Ultra capable chip (7859/7860). We start
|
|
|
|
* out with the AHC_ULTRA feature set and then check the DEVSTATUS
|
|
|
|
* register to determine if the capability is really present.
|
|
|
|
*/
|
|
|
|
AHC_AIC7850_FE = AHC_SPIOCAP|AHC_AUTOPAUSE|AHC_TARGETMODE|AHC_ULTRA,
|
|
|
|
AHC_AIC7860_FE = AHC_AIC7850_FE,
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
AHC_AIC7870_FE = AHC_TARGETMODE,
|
|
|
|
AHC_AIC7880_FE = AHC_AIC7870_FE|AHC_ULTRA,
|
|
|
|
/*
|
|
|
|
* Although we have space for both the initiator and
|
|
|
|
* target roles on ULTRA2 chips, we currently disable
|
|
|
|
* the initiator role to allow multi-scsi-id target mode
|
|
|
|
* configurations. We can only respond on the same SCSI
|
|
|
|
* ID as our initiator role if we allow initiator operation.
|
|
|
|
* At some point, we should add a configuration knob to
|
|
|
|
* allow both roles to be loaded.
|
|
|
|
*/
|
|
|
|
AHC_AIC7890_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA2
|
|
|
|
|AHC_QUEUE_REGS|AHC_SG_PRELOAD|AHC_MULTI_TID
|
2001-01-22 21:03:48 +00:00
|
|
|
|AHC_HS_MAILBOX|AHC_NEW_TERMCTL|AHC_LARGE_SCBS
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
|AHC_TARGETMODE,
|
2000-09-16 20:02:28 +00:00
|
|
|
AHC_AIC7892_FE = AHC_AIC7890_FE|AHC_DT|AHC_AUTORATE|AHC_AUTOPAUSE,
|
|
|
|
AHC_AIC7895_FE = AHC_AIC7880_FE|AHC_MORE_SRAM|AHC_AUTOPAUSE
|
2000-07-18 20:12:14 +00:00
|
|
|
|AHC_CMD_CHAN|AHC_MULTI_FUNC|AHC_LARGE_SCBS,
|
2000-01-07 23:08:20 +00:00
|
|
|
AHC_AIC7895C_FE = AHC_AIC7895_FE|AHC_MULTI_TID,
|
|
|
|
AHC_AIC7896_FE = AHC_AIC7890_FE|AHC_MULTI_FUNC,
|
|
|
|
AHC_AIC7899_FE = AHC_AIC7892_FE|AHC_MULTI_FUNC
|
1998-09-15 07:24:17 +00:00
|
|
|
} ahc_feature;
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Bugs in the silicon that we work around in software.
|
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
typedef enum {
|
|
|
|
AHC_BUGNONE = 0x00,
|
|
|
|
/*
|
|
|
|
* On all chips prior to the U2 product line,
|
|
|
|
* the WIDEODD S/G segment feature does not
|
|
|
|
* work during scsi->HostBus transfers.
|
|
|
|
*/
|
|
|
|
AHC_TMODE_WIDEODD_BUG = 0x01,
|
|
|
|
/*
|
|
|
|
* On the aic7890/91 Rev 0 chips, the autoflush
|
|
|
|
* feature does not work. A manual flush of
|
|
|
|
* the DMA FIFO is required.
|
|
|
|
*/
|
ahc_pci.c:
Disable "cache line streaming" for aic7890/91 Rev A chips. I
have never seen these chips fail using this feature, but
some of Adaptec's regression tests have.
Explicitly set "cache line streaming" to on for aic7896/97
chips. This was happening before, but this documents the
fact that these chips will not function correctly without
CACHETHEEN set.
aic7xxx.h:
Add new bug types.
Fix a typo in a comment.
aic7xxx.reg:
Add a definition for the SHVALID bit in SSTAT3 for Ultra2/3
chips. This bit inicates whether the bottom most (current)
element in the S/G fifo has exhausted its data count.
aic7xxx.seq:
Be more careful in how we turn off the secondary DMA channel.
Being less careful may hang the PCI bus arbitor that negotiates
between the two DMA engines.
Remove an unecessary and incorrect flag set operation in
the overrun case.
On Ultra2/3 controllers, clear the dma FIFO before starting
to handle an overrun. We don't want any residual bytes from
the beginning of the overrun to cause the code that shuts
down the DMA engine from hanging because the FIFO is not
(and never will be) empty.
If the data fifo is empty by the time we notice that a
read transaction has completed, there is no need to
hit the flush bit on aic7890/91 hardware that will not
perform an auto-flush. Skip some cycles by short circuiting
the manual flush code in this case.
When transitioning out of data phase, make sure that we
have the next S/G element loaded for the following
reconnect if there is more work to do. The code
would do this in most cases before, but there was
a small window where the current S/G element could
be exhausted before our fetch of the next S/G element
completed. Since the S/G fetch is already initiated
at this point, it makes sense to just wait for the
segment to arrive instead of incuring even more latency
by canceling the fetch and initiating it later.
Fast path the end of data phase handling for the last
S/G segment. In the general case, we might have
worked ahead a bit by stuffing the S/G FIFO with
additional segments. If we stop before using them
all, we need to fixup our location in the S/G stream.
Since we can't work past the last S/G segment, no
fixups are ever required if we stop somewhere in
that final segment.
Fix a little buglet in the target mode dma bug handler.
We were employing the workaround in all cases instead
of only for the chips that require it.
Fix the cause of SCB timeouts and possible "lost data"
during read operations on the aic7890. When sending
a data on any Ultra2/3 controller, the final segment
must be marked as such so the FIFO will be flushed and
cleaned up correctly when the transfer is ended. We
failed to do this for the CDB transfer and so, if
the target immediately transfered from command to data
phase without an intervening disconnection, the first
segment transferred would be any residual bytes from
the cdb transfer. The Ultra160 controllers for some
reason were not affected by this problem.
Many Thanks to Tor Egge for bringing the aic7890 problem
to my attention, providing analysis, as well as a mechanism
to reproduce the problem.
2000-07-27 23:17:52 +00:00
|
|
|
AHC_AUTOFLUSH_BUG = 0x02,
|
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* On many chips, cacheline streaming does not work.
|
ahc_pci.c:
Disable "cache line streaming" for aic7890/91 Rev A chips. I
have never seen these chips fail using this feature, but
some of Adaptec's regression tests have.
Explicitly set "cache line streaming" to on for aic7896/97
chips. This was happening before, but this documents the
fact that these chips will not function correctly without
CACHETHEEN set.
aic7xxx.h:
Add new bug types.
Fix a typo in a comment.
aic7xxx.reg:
Add a definition for the SHVALID bit in SSTAT3 for Ultra2/3
chips. This bit inicates whether the bottom most (current)
element in the S/G fifo has exhausted its data count.
aic7xxx.seq:
Be more careful in how we turn off the secondary DMA channel.
Being less careful may hang the PCI bus arbitor that negotiates
between the two DMA engines.
Remove an unecessary and incorrect flag set operation in
the overrun case.
On Ultra2/3 controllers, clear the dma FIFO before starting
to handle an overrun. We don't want any residual bytes from
the beginning of the overrun to cause the code that shuts
down the DMA engine from hanging because the FIFO is not
(and never will be) empty.
If the data fifo is empty by the time we notice that a
read transaction has completed, there is no need to
hit the flush bit on aic7890/91 hardware that will not
perform an auto-flush. Skip some cycles by short circuiting
the manual flush code in this case.
When transitioning out of data phase, make sure that we
have the next S/G element loaded for the following
reconnect if there is more work to do. The code
would do this in most cases before, but there was
a small window where the current S/G element could
be exhausted before our fetch of the next S/G element
completed. Since the S/G fetch is already initiated
at this point, it makes sense to just wait for the
segment to arrive instead of incuring even more latency
by canceling the fetch and initiating it later.
Fast path the end of data phase handling for the last
S/G segment. In the general case, we might have
worked ahead a bit by stuffing the S/G FIFO with
additional segments. If we stop before using them
all, we need to fixup our location in the S/G stream.
Since we can't work past the last S/G segment, no
fixups are ever required if we stop somewhere in
that final segment.
Fix a little buglet in the target mode dma bug handler.
We were employing the workaround in all cases instead
of only for the chips that require it.
Fix the cause of SCB timeouts and possible "lost data"
during read operations on the aic7890. When sending
a data on any Ultra2/3 controller, the final segment
must be marked as such so the FIFO will be flushed and
cleaned up correctly when the transfer is ended. We
failed to do this for the CDB transfer and so, if
the target immediately transfered from command to data
phase without an intervening disconnection, the first
segment transferred would be any residual bytes from
the cdb transfer. The Ultra160 controllers for some
reason were not affected by this problem.
Many Thanks to Tor Egge for bringing the aic7890 problem
to my attention, providing analysis, as well as a mechanism
to reproduce the problem.
2000-07-27 23:17:52 +00:00
|
|
|
*/
|
|
|
|
AHC_CACHETHEN_BUG = 0x04,
|
|
|
|
/*
|
|
|
|
* On the aic7896/97 chips, cacheline
|
|
|
|
* streaming must be enabled.
|
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
AHC_CACHETHEN_DIS_BUG = 0x08,
|
|
|
|
/*
|
|
|
|
* PCI 2.1 Retry failure on non-empty data fifo.
|
|
|
|
*/
|
|
|
|
AHC_PCI_2_1_RETRY_BUG = 0x10,
|
|
|
|
/*
|
|
|
|
* Controller does not handle cacheline residuals
|
|
|
|
* properly on S/G segments if PCI MWI instructions
|
|
|
|
* are allowed.
|
|
|
|
*/
|
|
|
|
AHC_PCI_MWI_BUG = 0x20,
|
|
|
|
/*
|
|
|
|
* An SCB upload using the SCB channel's
|
|
|
|
* auto array entry copy feature may
|
|
|
|
* corrupt data. This appears to only
|
|
|
|
* occur on 66MHz systems.
|
|
|
|
*/
|
|
|
|
AHC_SCBCHAN_UPLOAD_BUG = 0x40
|
2000-07-18 20:12:14 +00:00
|
|
|
} ahc_bug;
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Configuration specific settings.
|
|
|
|
* The driver determines these settings by probing the
|
|
|
|
* chip/controller's configuration.
|
|
|
|
*/
|
1998-09-15 07:24:17 +00:00
|
|
|
typedef enum {
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
AHC_FNONE = 0x000,
|
|
|
|
AHC_PRIMARY_CHANNEL = 0x003,/*
|
|
|
|
* The channel that should
|
|
|
|
* be probed first.
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
AHC_USEDEFAULTS = 0x004,/*
|
1998-09-15 07:24:17 +00:00
|
|
|
* For cards without an seeprom
|
|
|
|
* or a BIOS to initialize the chip's
|
|
|
|
* SRAM, we use the default target
|
|
|
|
* settings.
|
|
|
|
*/
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
AHC_SEQUENCER_DEBUG = 0x008,
|
|
|
|
AHC_SHARED_SRAM = 0x010,
|
|
|
|
AHC_LARGE_SEEPROM = 0x020,/* Uses C56_66 not C46 */
|
|
|
|
AHC_RESET_BUS_A = 0x040,
|
|
|
|
AHC_RESET_BUS_B = 0x080,
|
|
|
|
AHC_EXTENDED_TRANS_A = 0x100,
|
|
|
|
AHC_EXTENDED_TRANS_B = 0x200,
|
|
|
|
AHC_TERM_ENB_A = 0x400,
|
|
|
|
AHC_TERM_ENB_B = 0x800,
|
|
|
|
AHC_INITIATORROLE = 0x1000,/*
|
1998-12-10 04:14:50 +00:00
|
|
|
* Allow initiator operations on
|
|
|
|
* this controller.
|
|
|
|
*/
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
AHC_TARGETROLE = 0x2000,/*
|
1998-09-15 07:24:17 +00:00
|
|
|
* Allow target operations on this
|
|
|
|
* controller.
|
|
|
|
*/
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
AHC_NEWEEPROM_FMT = 0x4000,
|
|
|
|
AHC_RESOURCE_SHORTAGE = 0x8000,
|
|
|
|
AHC_TQINFIFO_BLOCKED = 0x10000,/* Blocked waiting for ATIOs */
|
|
|
|
AHC_INT50_SPEEDFLEX = 0x20000,/*
|
2000-01-07 23:08:20 +00:00
|
|
|
* Internal 50pin connector
|
|
|
|
* sits behind an aic3860
|
|
|
|
*/
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
AHC_SCB_BTT = 0x40000,/*
|
2000-07-18 20:12:14 +00:00
|
|
|
* The busy targets table is
|
|
|
|
* stored in SCB space rather
|
|
|
|
* than SRAM.
|
|
|
|
*/
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
AHC_BIOS_ENABLED = 0x80000,
|
|
|
|
AHC_ALL_INTERRUPTS = 0x100000,
|
2002-08-31 06:42:10 +00:00
|
|
|
AHC_PAGESCBS = 0x400000, /* Enable SCB paging */
|
|
|
|
AHC_EDGE_INTERRUPT = 0x800000, /* Device uses edge triggered ints */
|
|
|
|
AHC_39BIT_ADDRESSING = 0x1000000, /* Use 39 bit addressing scheme. */
|
|
|
|
AHC_LSCBS_ENABLED = 0x2000000, /* 64Byte SCBs enabled */
|
|
|
|
AHC_SCB_CONFIG_USED = 0x4000000 /* No SEEPROM but SCB2 had info. */
|
1998-09-15 07:24:17 +00:00
|
|
|
} ahc_flag;
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/************************* Hardware SCB Definition ***************************/
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The driver keeps up to MAX_SCB scb structures per card in memory. The SCB
|
|
|
|
* consists of a "hardware SCB" mirroring the fields availible on the card
|
|
|
|
* and additional information the kernel stores for each transaction.
|
2000-07-18 20:12:14 +00:00
|
|
|
*
|
|
|
|
* To minimize space utilization, a portion of the hardware scb stores
|
|
|
|
* different data during different portions of a SCSI transaction.
|
|
|
|
* As initialized by the host driver for the initiator role, this area
|
2000-09-16 20:02:28 +00:00
|
|
|
* contains the SCSI cdb (or a pointer to the cdb) to be executed. After
|
2000-07-18 20:12:14 +00:00
|
|
|
* the cdb has been presented to the target, this area serves to store
|
|
|
|
* residual transfer information and the SCSI status byte.
|
|
|
|
* For the target role, the contents of this area do not change, but
|
|
|
|
* still serve a different purpose than for the initiator role. See
|
|
|
|
* struct target_data for details.
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Status information embedded in the shared poriton of
|
|
|
|
* an SCB after passing the cdb to the target. The kernel
|
|
|
|
* driver will only read this data for transactions that
|
|
|
|
* complete abnormally (non-zero status byte).
|
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
struct status_pkt {
|
2000-09-16 20:02:28 +00:00
|
|
|
uint32_t residual_datacnt; /* Residual in the current S/G seg */
|
|
|
|
uint32_t residual_sg_ptr; /* The next S/G for this transfer */
|
|
|
|
uint8_t scsi_status; /* Standard SCSI status byte */
|
2000-07-18 20:12:14 +00:00
|
|
|
};
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Target mode version of the shared data SCB segment.
|
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
struct target_data {
|
2002-04-24 16:58:51 +00:00
|
|
|
uint32_t residual_datacnt; /* Residual in the current S/G seg */
|
|
|
|
uint32_t residual_sg_ptr; /* The next S/G for this transfer */
|
|
|
|
uint8_t scsi_status; /* SCSI status to give to initiator */
|
|
|
|
uint8_t target_phases; /* Bitmap of phases to execute */
|
|
|
|
uint8_t data_phase; /* Data-In or Data-Out */
|
|
|
|
uint8_t initiator_tag; /* Initiator's transaction tag */
|
2000-07-18 20:12:14 +00:00
|
|
|
};
|
|
|
|
|
1998-09-15 07:24:17 +00:00
|
|
|
struct hardware_scb {
|
2000-09-16 20:02:28 +00:00
|
|
|
/*0*/ union {
|
2000-07-18 20:12:14 +00:00
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* If the cdb is 12 bytes or less, we embed it directly
|
|
|
|
* in the SCB. For longer cdbs, we embed the address
|
|
|
|
* of the cdb payload as seen by the chip and a DMA
|
|
|
|
* is used to pull it in.
|
2000-07-18 20:12:14 +00:00
|
|
|
*/
|
2002-04-24 16:58:51 +00:00
|
|
|
uint8_t cdb[12];
|
|
|
|
uint32_t cdb_ptr;
|
|
|
|
struct status_pkt status;
|
|
|
|
struct target_data tdata;
|
2000-07-18 20:12:14 +00:00
|
|
|
} shared_data;
|
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* A word about residuals.
|
|
|
|
* The scb is presented to the sequencer with the dataptr and datacnt
|
|
|
|
* fields initialized to the contents of the first S/G element to
|
|
|
|
* transfer. The sgptr field is initialized to the bus address for
|
|
|
|
* the S/G element that follows the first in the in core S/G array
|
|
|
|
* or'ed with the SG_FULL_RESID flag. Sgptr may point to an invalid
|
|
|
|
* S/G entry for this transfer (single S/G element transfer with the
|
|
|
|
* first elements address and length preloaded in the dataptr/datacnt
|
|
|
|
* fields). If no transfer is to occur, sgptr is set to SG_LIST_NULL.
|
|
|
|
* The SG_FULL_RESID flag ensures that the residual will be correctly
|
|
|
|
* noted even if no data transfers occur. Once the data phase is entered,
|
|
|
|
* the residual sgptr and datacnt are loaded from the sgptr and the
|
|
|
|
* datacnt fields. After each S/G element's dataptr and length are
|
|
|
|
* loaded into the hardware, the residual sgptr is advanced. After
|
|
|
|
* each S/G element is expired, its datacnt field is checked to see
|
|
|
|
* if the LAST_SEG flag is set. If so, SG_LIST_NULL is set in the
|
|
|
|
* residual sg ptr and the transfer is considered complete. If the
|
|
|
|
* sequencer determines that there is a residual in the tranfer, it
|
|
|
|
* will set the SG_RESID_VALID flag in sgptr and dma the scb back into
|
2000-07-18 20:12:14 +00:00
|
|
|
* host memory. To sumarize:
|
|
|
|
*
|
|
|
|
* Sequencer:
|
|
|
|
* o A residual has occurred if SG_FULL_RESID is set in sgptr,
|
|
|
|
* or residual_sgptr does not have SG_LIST_NULL set.
|
|
|
|
*
|
|
|
|
* o We are transfering the last segment if residual_datacnt has
|
|
|
|
* the SG_LAST_SEG flag set.
|
|
|
|
*
|
|
|
|
* Host:
|
|
|
|
* o A residual has occurred if a completed scb has the
|
|
|
|
* SG_RESID_VALID flag set.
|
|
|
|
*
|
|
|
|
* o residual_sgptr and sgptr refer to the "next" sg entry
|
|
|
|
* and so may point beyond the last valid sg entry for the
|
|
|
|
* transfer.
|
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
/*12*/ uint32_t dataptr;
|
|
|
|
/*16*/ uint32_t datacnt; /*
|
|
|
|
* Byte 3 (numbered from 0) of
|
|
|
|
* the datacnt is really the
|
|
|
|
* 4th byte in that data address.
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
/*20*/ uint32_t sgptr;
|
2000-07-18 20:12:14 +00:00
|
|
|
#define SG_PTR_MASK 0xFFFFFFF8
|
2000-09-16 20:02:28 +00:00
|
|
|
/*24*/ uint8_t control; /* See SCB_CONTROL in aic7xxx.reg for details */
|
|
|
|
/*25*/ uint8_t scsiid; /* what to load in the SCSIID register */
|
|
|
|
/*26*/ uint8_t lun;
|
|
|
|
/*27*/ uint8_t tag; /*
|
|
|
|
* Index into our kernel SCB array.
|
1998-09-15 07:24:17 +00:00
|
|
|
* Also used as the tag for tagged I/O
|
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
/*28*/ uint8_t cdb_len;
|
2000-07-18 20:12:14 +00:00
|
|
|
/*29*/ uint8_t scsirate; /* Value for SCSIRATE register */
|
|
|
|
/*30*/ uint8_t scsioffset; /* Value for SCSIOFFSET register */
|
2000-09-16 20:02:28 +00:00
|
|
|
/*31*/ uint8_t next; /*
|
|
|
|
* Used for threading SCBs in the
|
1998-09-15 07:24:17 +00:00
|
|
|
* "Waiting for Selection" and
|
|
|
|
* "Disconnected SCB" lists down
|
|
|
|
* in the sequencer.
|
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
/*32*/ uint8_t cdb32[32]; /*
|
2000-09-16 20:02:28 +00:00
|
|
|
* CDB storage for cdbs of size
|
|
|
|
* 13->32. We store them here
|
|
|
|
* because hardware scbs are
|
|
|
|
* allocated from DMA safe
|
|
|
|
* memory so we are guaranteed
|
|
|
|
* the controller can access
|
|
|
|
* this data.
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
|
|
|
};
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/************************ Kernel SCB Definitions ******************************/
|
|
|
|
/*
|
|
|
|
* Some fields of the SCB are OS dependent. Here we collect the
|
|
|
|
* definitions for elements that all OS platforms need to include
|
|
|
|
* in there SCB definition.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Definition of a scatter/gather element as transfered to the controller.
|
|
|
|
* The aic7xxx chips only support a 24bit length. We use the top byte of
|
|
|
|
* the length to store additional address bits and a flag to indicate
|
|
|
|
* that a given segment terminates the transfer. This gives us an
|
|
|
|
* addressable range of 512GB on machines with 64bit PCI or with chips
|
|
|
|
* that can support dual address cycles on 32bit PCI busses.
|
|
|
|
*/
|
|
|
|
struct ahc_dma_seg {
|
|
|
|
uint32_t addr;
|
|
|
|
uint32_t len;
|
|
|
|
#define AHC_DMA_LAST_SEG 0x80000000
|
|
|
|
#define AHC_SG_HIGH_ADDR_MASK 0x7F000000
|
|
|
|
#define AHC_SG_LEN_MASK 0x00FFFFFF
|
|
|
|
};
|
|
|
|
|
2001-07-18 21:39:48 +00:00
|
|
|
struct sg_map_node {
|
|
|
|
bus_dmamap_t sg_dmamap;
|
|
|
|
bus_addr_t sg_physaddr;
|
|
|
|
struct ahc_dma_seg* sg_vaddr;
|
|
|
|
SLIST_ENTRY(sg_map_node) links;
|
|
|
|
};
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* The current state of this SCB.
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
SCB_FREE = 0x0000,
|
|
|
|
SCB_OTHERTCL_TIMEOUT = 0x0002,/*
|
|
|
|
* Another device was active
|
|
|
|
* during the first timeout for
|
|
|
|
* this SCB so we gave ourselves
|
|
|
|
* an additional timeout period
|
|
|
|
* in case it was hogging the
|
|
|
|
* bus.
|
|
|
|
*/
|
|
|
|
SCB_DEVICE_RESET = 0x0004,
|
|
|
|
SCB_SENSE = 0x0008,
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
SCB_CDB32_PTR = 0x0010,
|
2001-03-29 00:36:35 +00:00
|
|
|
SCB_RECOVERY_SCB = 0x0020,
|
|
|
|
SCB_AUTO_NEGOTIATE = 0x0040,/* Negotiate to achieve goal. */
|
|
|
|
SCB_NEGOTIATE = 0x0080,/* Negotiation forced for command. */
|
2000-09-16 20:02:28 +00:00
|
|
|
SCB_ABORT = 0x1000,
|
2000-10-11 23:46:34 +00:00
|
|
|
SCB_UNTAGGEDQ = 0x2000,
|
2000-09-16 20:02:28 +00:00
|
|
|
SCB_ACTIVE = 0x4000,
|
|
|
|
SCB_TARGET_IMMEDIATE = 0x8000
|
|
|
|
} scb_flag;
|
|
|
|
|
1998-09-15 07:24:17 +00:00
|
|
|
struct scb {
|
2000-09-16 20:02:28 +00:00
|
|
|
struct hardware_scb *hscb;
|
2000-07-18 20:12:14 +00:00
|
|
|
union {
|
2000-09-16 20:02:28 +00:00
|
|
|
SLIST_ENTRY(scb) sle;
|
|
|
|
TAILQ_ENTRY(scb) tqe;
|
2000-07-18 20:12:14 +00:00
|
|
|
} links;
|
2000-09-16 20:02:28 +00:00
|
|
|
LIST_ENTRY(scb) pending_links;
|
|
|
|
ahc_io_ctx_t io_ctx;
|
2000-10-11 23:46:34 +00:00
|
|
|
struct ahc_softc *ahc_softc;
|
2000-09-16 20:02:28 +00:00
|
|
|
scb_flag flags;
|
|
|
|
#ifndef __linux__
|
|
|
|
bus_dmamap_t dmamap;
|
|
|
|
#endif
|
|
|
|
struct scb_platform_data *platform_data;
|
2001-07-18 21:39:48 +00:00
|
|
|
struct sg_map_node *sg_map;
|
|
|
|
struct ahc_dma_seg *sg_list;
|
2000-09-16 20:02:28 +00:00
|
|
|
bus_addr_t sg_list_phys;
|
|
|
|
u_int sg_count;/* How full ahc_dma_seg is */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct scb_data {
|
|
|
|
SLIST_HEAD(, scb) free_scbs; /*
|
|
|
|
* Pool of SCBs ready to be assigned
|
|
|
|
* commands to execute.
|
|
|
|
*/
|
2002-04-24 16:58:51 +00:00
|
|
|
struct scb *scbindex[256]; /*
|
|
|
|
* Mapping from tag to SCB.
|
|
|
|
* As tag identifiers are an
|
|
|
|
* 8bit value, we provide space
|
|
|
|
* for all possible tag values.
|
|
|
|
* Any lookups to entries at or
|
|
|
|
* above AHC_SCB_MAX_ALLOC will
|
|
|
|
* always fail.
|
|
|
|
*/
|
2000-10-05 04:24:14 +00:00
|
|
|
struct hardware_scb *hscbs; /* Array of hardware SCBs */
|
|
|
|
struct scb *scbarray; /* Array of kernel SCBs */
|
2000-09-16 20:02:28 +00:00
|
|
|
struct scsi_sense_data *sense; /* Per SCB sense data */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "Bus" addresses of our data structures.
|
|
|
|
*/
|
|
|
|
bus_dma_tag_t hscb_dmat; /* dmat for our hardware SCB array */
|
|
|
|
bus_dmamap_t hscb_dmamap;
|
|
|
|
bus_addr_t hscb_busaddr;
|
|
|
|
bus_dma_tag_t sense_dmat;
|
|
|
|
bus_dmamap_t sense_dmamap;
|
|
|
|
bus_addr_t sense_busaddr;
|
|
|
|
bus_dma_tag_t sg_dmat; /* dmat for our sg segments */
|
|
|
|
SLIST_HEAD(, sg_map_node) sg_maps;
|
|
|
|
uint8_t numscbs;
|
|
|
|
uint8_t maxhscbs; /* Number of SCBs on the card */
|
|
|
|
uint8_t init_level; /*
|
|
|
|
* How far we've initialized
|
|
|
|
* this structure.
|
|
|
|
*/
|
1998-09-15 07:24:17 +00:00
|
|
|
};
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/************************ Target Mode Definitions *****************************/
|
|
|
|
|
1998-09-15 07:24:17 +00:00
|
|
|
/*
|
|
|
|
* Connection desciptor for select-in requests in target mode.
|
|
|
|
*/
|
|
|
|
struct target_cmd {
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t scsiid; /* Our ID and the initiator's ID */
|
2000-07-18 20:12:14 +00:00
|
|
|
uint8_t identify; /* Identify message */
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t bytes[22]; /*
|
|
|
|
* Bytes contains any additional message
|
|
|
|
* bytes terminated by 0xFF. The remainder
|
|
|
|
* is the cdb to execute.
|
|
|
|
*/
|
|
|
|
uint8_t cmd_valid; /*
|
|
|
|
* When a command is complete, the firmware
|
|
|
|
* will set cmd_valid to all bits set.
|
|
|
|
* After the host has seen the command,
|
|
|
|
* the bits are cleared. This allows us
|
|
|
|
* to just peek at host memory to determine
|
|
|
|
* if more work is complete. cmd_valid is on
|
|
|
|
* an 8 byte boundary to simplify setting
|
|
|
|
* it on aic7880 hardware which only has
|
|
|
|
* limited direct access to the DMA FIFO.
|
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
uint8_t pad[7];
|
1998-09-15 07:24:17 +00:00
|
|
|
};
|
|
|
|
|
1999-08-16 22:49:29 +00:00
|
|
|
/*
|
|
|
|
* Number of events we can buffer up if we run out
|
|
|
|
* of immediate notify ccbs.
|
|
|
|
*/
|
|
|
|
#define AHC_TMODE_EVENT_BUFFER_SIZE 8
|
|
|
|
struct ahc_tmode_event {
|
2000-07-18 20:12:14 +00:00
|
|
|
uint8_t initiator_id;
|
|
|
|
uint8_t event_type; /* MSG type or EVENT_TYPE_BUS_RESET */
|
1999-08-16 22:49:29 +00:00
|
|
|
#define EVENT_TYPE_BUS_RESET 0xFF
|
2000-07-18 20:12:14 +00:00
|
|
|
uint8_t event_arg;
|
1999-08-16 22:49:29 +00:00
|
|
|
};
|
|
|
|
|
1998-09-15 07:24:17 +00:00
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* Per enabled lun target mode state.
|
|
|
|
* As this state is directly influenced by the host OS'es target mode
|
|
|
|
* environment, we let the OS module define it. Forward declare the
|
|
|
|
* structure here so we can store arrays of them, etc. in OS neutral
|
|
|
|
* data structures.
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
#ifdef AHC_TARGET_MODE
|
2001-03-29 00:36:35 +00:00
|
|
|
struct ahc_tmode_lstate {
|
1999-08-16 22:49:29 +00:00
|
|
|
struct cam_path *path;
|
1998-12-15 08:22:42 +00:00
|
|
|
struct ccb_hdr_slist accept_tios;
|
|
|
|
struct ccb_hdr_slist immed_notifies;
|
1999-08-16 22:49:29 +00:00
|
|
|
struct ahc_tmode_event event_buffer[AHC_TMODE_EVENT_BUFFER_SIZE];
|
2000-07-18 20:12:14 +00:00
|
|
|
uint8_t event_r_idx;
|
|
|
|
uint8_t event_w_idx;
|
1998-09-15 07:24:17 +00:00
|
|
|
};
|
2000-09-16 20:02:28 +00:00
|
|
|
#else
|
2001-03-29 00:36:35 +00:00
|
|
|
struct ahc_tmode_lstate;
|
2000-09-16 20:02:28 +00:00
|
|
|
#endif
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/******************** Transfer Negotiation Datastructures *********************/
|
1999-03-05 23:35:48 +00:00
|
|
|
#define AHC_TRANS_CUR 0x01 /* Modify current neogtiation status */
|
2000-09-16 20:02:28 +00:00
|
|
|
#define AHC_TRANS_ACTIVE 0x03 /* Assume this target is on the bus */
|
1999-03-05 23:35:48 +00:00
|
|
|
#define AHC_TRANS_GOAL 0x04 /* Modify negotiation goal */
|
|
|
|
#define AHC_TRANS_USER 0x08 /* Modify user negotiation settings */
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Transfer Negotiation Information.
|
|
|
|
*/
|
1999-03-05 23:35:48 +00:00
|
|
|
struct ahc_transinfo {
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t protocol_version; /* SCSI Revision level */
|
|
|
|
uint8_t transport_version; /* SPI Revision level */
|
|
|
|
uint8_t width; /* Bus width */
|
|
|
|
uint8_t period; /* Sync rate factor */
|
|
|
|
uint8_t offset; /* Sync offset */
|
|
|
|
uint8_t ppr_options; /* Parallel Protocol Request options */
|
1999-03-05 23:35:48 +00:00
|
|
|
};
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Per-initiator current, goal and user transfer negotiation information. */
|
1999-03-05 23:35:48 +00:00
|
|
|
struct ahc_initiator_tinfo {
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t scsirate; /* Computed value for SCSIRATE reg */
|
2001-05-15 19:41:12 +00:00
|
|
|
struct ahc_transinfo curr;
|
1999-03-05 23:35:48 +00:00
|
|
|
struct ahc_transinfo goal;
|
|
|
|
struct ahc_transinfo user;
|
|
|
|
};
|
|
|
|
|
1998-09-15 07:24:17 +00:00
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* Per enabled target ID state.
|
|
|
|
* Pointers to lun target state as well as sync/wide negotiation information
|
|
|
|
* for each initiator<->target mapping. For the initiator role we pretend
|
|
|
|
* that we are the target and the targets are the initiators since the
|
|
|
|
* negotiation is the same regardless of role.
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
2001-03-29 00:36:35 +00:00
|
|
|
struct ahc_tmode_tstate {
|
|
|
|
struct ahc_tmode_lstate* enabled_luns[AHC_NUM_LUNS];
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
struct ahc_initiator_tinfo transinfo[AHC_NUM_TARGETS];
|
1999-03-05 23:35:48 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Per initiator state bitmasks.
|
|
|
|
*/
|
2001-03-29 00:36:35 +00:00
|
|
|
uint16_t auto_negotiate;/* Auto Negotiation Required */
|
|
|
|
uint16_t ultraenb; /* Using ultra sync rate */
|
|
|
|
uint16_t discenable; /* Disconnection allowed */
|
|
|
|
uint16_t tagenable; /* Tagged Queuing allowed */
|
1998-09-15 07:24:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* Data structure for our table of allowed synchronous transfer rates.
|
|
|
|
*/
|
|
|
|
struct ahc_syncrate {
|
|
|
|
u_int sxfr_u2; /* Value of the SXFR parameter for Ultra2+ Chips */
|
|
|
|
u_int sxfr; /* Value of the SXFR parameter for <= Ultra Chips */
|
|
|
|
#define ULTRA_SXFR 0x100 /* Rate Requires Ultra Mode set */
|
|
|
|
#define ST_SXFR 0x010 /* Rate Single Transition Only */
|
|
|
|
#define DT_SXFR 0x040 /* Rate Double Transition Only */
|
|
|
|
uint8_t period; /* Period to send to SCSI target */
|
|
|
|
char *rate;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Indexes into our table of syncronous transfer rates.
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
#define AHC_SYNCRATE_DT 0
|
|
|
|
#define AHC_SYNCRATE_ULTRA2 1
|
|
|
|
#define AHC_SYNCRATE_ULTRA 3
|
|
|
|
#define AHC_SYNCRATE_FAST 6
|
|
|
|
|
|
|
|
/***************************** Lookup Tables **********************************/
|
|
|
|
/*
|
|
|
|
* Phase -> name and message out response
|
|
|
|
* to parity errors in each phase table.
|
|
|
|
*/
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
struct ahc_phase_table_entry {
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t phase;
|
|
|
|
uint8_t mesg_out; /* Message response to parity errors */
|
|
|
|
char *phasemsg;
|
|
|
|
};
|
|
|
|
|
|
|
|
/************************** Serial EEPROM Format ******************************/
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
struct seeprom_config {
|
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* Per SCSI ID Configuration Flags
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
uint16_t device_flags[16]; /* words 0-15 */
|
1998-09-15 07:24:17 +00:00
|
|
|
#define CFXFER 0x0007 /* synchronous transfer rate */
|
|
|
|
#define CFSYNCH 0x0008 /* enable synchronous transfer */
|
|
|
|
#define CFDISC 0x0010 /* enable disconnection */
|
|
|
|
#define CFWIDEB 0x0020 /* wide bus device */
|
|
|
|
#define CFSYNCHISULTRA 0x0040 /* CFSYNCH is an ultra offset (2940AU)*/
|
2000-01-07 23:08:20 +00:00
|
|
|
#define CFSYNCSINGLE 0x0080 /* Single-Transition signalling */
|
1998-09-15 07:24:17 +00:00
|
|
|
#define CFSTART 0x0100 /* send start unit SCSI command */
|
|
|
|
#define CFINCBIOS 0x0200 /* include in BIOS scan */
|
|
|
|
#define CFRNFOUND 0x0400 /* report even if not found */
|
2000-07-18 20:12:14 +00:00
|
|
|
#define CFMULTILUNDEV 0x0800 /* Probe multiple luns in BIOS scan */
|
2000-01-07 23:08:20 +00:00
|
|
|
#define CFWBCACHEENB 0x4000 /* Enable W-Behind Cache on disks */
|
|
|
|
#define CFWBCACHENOP 0xc000 /* Don't touch W-Behind Cache */
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* BIOS Control Bits
|
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
uint16_t bios_control; /* word 16 */
|
1998-09-15 07:24:17 +00:00
|
|
|
#define CFSUPREM 0x0001 /* support all removeable drives */
|
2000-01-07 23:08:20 +00:00
|
|
|
#define CFSUPREMB 0x0002 /* support removeable boot drives */
|
1998-09-15 07:24:17 +00:00
|
|
|
#define CFBIOSEN 0x0004 /* BIOS enabled */
|
2001-05-15 19:41:12 +00:00
|
|
|
#define CFBIOS_BUSSCAN 0x0008 /* Have the BIOS Scan the Bus */
|
1998-09-15 07:24:17 +00:00
|
|
|
#define CFSM2DRV 0x0010 /* support more than two drives */
|
2000-07-18 20:12:14 +00:00
|
|
|
#define CFSTPWLEVEL 0x0010 /* Termination level control */
|
2001-05-15 19:41:12 +00:00
|
|
|
#define CF284XEXTEND 0x0020 /* extended translation (284x cards) */
|
|
|
|
#define CFCTRL_A 0x0020 /* BIOS displays Ctrl-A message */
|
|
|
|
#define CFTERM_MENU 0x0040 /* BIOS displays termination menu */
|
1998-09-15 07:24:17 +00:00
|
|
|
#define CFEXTEND 0x0080 /* extended translation enabled */
|
2000-07-18 20:12:14 +00:00
|
|
|
#define CFSCAMEN 0x0100 /* SCAM enable */
|
2001-05-15 19:41:12 +00:00
|
|
|
#define CFMSG_LEVEL 0x0600 /* BIOS Message Level */
|
|
|
|
#define CFMSG_VERBOSE 0x0000
|
|
|
|
#define CFMSG_SILENT 0x0200
|
|
|
|
#define CFMSG_DIAG 0x0400
|
|
|
|
#define CFBOOTCD 0x0800 /* Support Bootable CD-ROM */
|
1998-09-15 07:24:17 +00:00
|
|
|
/* UNUSED 0xff00 */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Host Adapter Control Bits
|
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
uint16_t adapter_control; /* word 17 */
|
1998-09-15 07:24:17 +00:00
|
|
|
#define CFAUTOTERM 0x0001 /* Perform Auto termination */
|
|
|
|
#define CFULTRAEN 0x0002 /* Ultra SCSI speed enable */
|
|
|
|
#define CF284XSELTO 0x0003 /* Selection timeout (284x cards) */
|
|
|
|
#define CF284XFIFO 0x000C /* FIFO Threshold (284x cards) */
|
|
|
|
#define CFSTERM 0x0004 /* SCSI low byte termination */
|
|
|
|
#define CFWSTERM 0x0008 /* SCSI high byte termination */
|
|
|
|
#define CFSPARITY 0x0010 /* SCSI parity */
|
|
|
|
#define CF284XSTERM 0x0020 /* SCSI low byte term (284x cards) */
|
2001-05-15 19:41:12 +00:00
|
|
|
#define CFMULTILUN 0x0020
|
1998-09-15 07:24:17 +00:00
|
|
|
#define CFRESETB 0x0040 /* reset SCSI bus at boot */
|
2000-07-18 20:12:14 +00:00
|
|
|
#define CFCLUSTERENB 0x0080 /* Cluster Enable */
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
#define CFBOOTCHAN 0x0300 /* probe this channel first */
|
|
|
|
#define CFBOOTCHANSHIFT 8
|
2000-07-18 20:12:14 +00:00
|
|
|
#define CFSEAUTOTERM 0x0400 /* Ultra2 Perform secondary Auto Term*/
|
|
|
|
#define CFSELOWTERM 0x0800 /* Ultra2 secondary low term */
|
|
|
|
#define CFSEHIGHTERM 0x1000 /* Ultra2 secondary high term */
|
|
|
|
#define CFDOMAINVAL 0x4000 /* Perform Domain Validation*/
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* Bus Release Time, Host Adapter ID
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
uint16_t brtime_id; /* word 18 */
|
1998-09-15 07:24:17 +00:00
|
|
|
#define CFSCSIID 0x000f /* host adapter SCSI ID */
|
|
|
|
/* UNUSED 0x00f0 */
|
|
|
|
#define CFBRTIME 0xff00 /* bus release time */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Maximum targets
|
|
|
|
*/
|
2000-07-18 20:12:14 +00:00
|
|
|
uint16_t max_targets; /* word 19 */
|
1998-09-15 07:24:17 +00:00
|
|
|
#define CFMAXTARG 0x00ff /* maximum targets */
|
2000-07-18 20:12:14 +00:00
|
|
|
#define CFBOOTLUN 0x0f00 /* Lun to boot from */
|
|
|
|
#define CFBOOTID 0xf000 /* Target to boot from */
|
|
|
|
uint16_t res_1[10]; /* words 20-29 */
|
|
|
|
uint16_t signature; /* Signature == 0x250 */
|
|
|
|
#define CFSIGNATURE 0x250
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
#define CFSIGNATURE2 0x300
|
2000-07-18 20:12:14 +00:00
|
|
|
uint16_t checksum; /* word 31 */
|
1998-09-15 07:24:17 +00:00
|
|
|
};
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/**************************** Message Buffer *********************************/
|
1998-09-15 07:24:17 +00:00
|
|
|
typedef enum {
|
|
|
|
MSG_TYPE_NONE = 0x00,
|
|
|
|
MSG_TYPE_INITIATOR_MSGOUT = 0x01,
|
1998-12-10 04:14:50 +00:00
|
|
|
MSG_TYPE_INITIATOR_MSGIN = 0x02,
|
|
|
|
MSG_TYPE_TARGET_MSGOUT = 0x03,
|
|
|
|
MSG_TYPE_TARGET_MSGIN = 0x04
|
1998-09-15 07:24:17 +00:00
|
|
|
} ahc_msg_type;
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
typedef enum {
|
|
|
|
MSGLOOP_IN_PROG,
|
|
|
|
MSGLOOP_MSGCOMPLETE,
|
|
|
|
MSGLOOP_TERMINATED
|
|
|
|
} msg_loop_stat;
|
1999-04-23 23:27:31 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*********************** Software Configuration Structure *********************/
|
2000-07-18 20:12:14 +00:00
|
|
|
TAILQ_HEAD(scb_tailq, scb);
|
|
|
|
|
2001-01-05 19:15:37 +00:00
|
|
|
struct ahc_suspend_channel_state {
|
|
|
|
uint8_t scsiseq;
|
|
|
|
uint8_t sxfrctl0;
|
|
|
|
uint8_t sxfrctl1;
|
|
|
|
uint8_t simode0;
|
|
|
|
uint8_t simode1;
|
|
|
|
uint8_t seltimer;
|
|
|
|
uint8_t seqctl;
|
|
|
|
};
|
|
|
|
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
struct ahc_suspend_state {
|
2001-01-05 19:15:37 +00:00
|
|
|
struct ahc_suspend_channel_state channel[2];
|
|
|
|
uint8_t optionmode;
|
|
|
|
uint8_t dscommand0;
|
|
|
|
uint8_t dspcistatus;
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
/* hsmailbox */
|
2001-01-05 19:15:37 +00:00
|
|
|
uint8_t crccontrol1;
|
|
|
|
uint8_t scbbaddr;
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
/* Host and sequencer SCB counts */
|
2001-01-05 19:15:37 +00:00
|
|
|
uint8_t dff_thrsh;
|
|
|
|
uint8_t *scratch_ram;
|
|
|
|
uint8_t *btt;
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
};
|
|
|
|
|
2001-03-29 00:36:35 +00:00
|
|
|
typedef void (*ahc_bus_intr_t)(struct ahc_softc *);
|
|
|
|
|
1998-09-15 07:24:17 +00:00
|
|
|
struct ahc_softc {
|
2000-09-16 20:02:28 +00:00
|
|
|
bus_space_tag_t tag;
|
|
|
|
bus_space_handle_t bsh;
|
|
|
|
#ifndef __linux__
|
|
|
|
bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
|
|
|
|
#endif
|
|
|
|
struct scb_data *scb_data;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-10-05 04:24:14 +00:00
|
|
|
struct scb *next_queued_scb;
|
|
|
|
|
1998-09-15 07:24:17 +00:00
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* SCBs that have been sent to the controller
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
2001-07-18 21:39:48 +00:00
|
|
|
LIST_HEAD(, scb) pending_scbs;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-07-18 20:12:14 +00:00
|
|
|
/*
|
|
|
|
* Counting lock for deferring the release of additional
|
|
|
|
* untagged transactions from the untagged_queues. When
|
|
|
|
* the lock is decremented to 0, all queues in the
|
|
|
|
* untagged_queues array are run.
|
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
u_int untagged_queue_lock;
|
2000-07-18 20:12:14 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Per-target queue of untagged-transactions. The
|
|
|
|
* transaction at the head of the queue is the
|
|
|
|
* currently pending untagged transaction for the
|
|
|
|
* target. The driver only allows a single untagged
|
|
|
|
* transaction per target.
|
|
|
|
*/
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
struct scb_tailq untagged_queues[AHC_NUM_TARGETS];
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Platform specific data.
|
|
|
|
*/
|
|
|
|
struct ahc_platform_data *platform_data;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Platform specific device information.
|
|
|
|
*/
|
|
|
|
ahc_dev_softc_t dev_softc;
|
2000-07-18 20:12:14 +00:00
|
|
|
|
2001-03-29 00:36:35 +00:00
|
|
|
/*
|
|
|
|
* Bus specific device information.
|
|
|
|
*/
|
|
|
|
ahc_bus_intr_t bus_intr;
|
|
|
|
|
1998-09-15 07:24:17 +00:00
|
|
|
/*
|
|
|
|
* Target mode related state kept on a per enabled lun basis.
|
|
|
|
* Targets that are not enabled will have null entries.
|
1999-03-05 23:35:48 +00:00
|
|
|
* As an initiator, we keep one target entry for our initiator
|
|
|
|
* ID to store our sync/wide transfer settings.
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
2001-03-29 00:36:35 +00:00
|
|
|
struct ahc_tmode_tstate *enabled_targets[AHC_NUM_TARGETS];
|
1998-09-15 07:24:17 +00:00
|
|
|
|
1999-01-14 06:14:15 +00:00
|
|
|
/*
|
|
|
|
* The black hole device responsible for handling requests for
|
|
|
|
* disabled luns on enabled targets.
|
|
|
|
*/
|
2001-03-29 00:36:35 +00:00
|
|
|
struct ahc_tmode_lstate *black_hole;
|
1999-01-14 06:14:15 +00:00
|
|
|
|
1998-09-15 07:24:17 +00:00
|
|
|
/*
|
|
|
|
* Device instance currently on the bus awaiting a continue TIO
|
|
|
|
* for a command that was not given the disconnect priveledge.
|
|
|
|
*/
|
2001-03-29 00:36:35 +00:00
|
|
|
struct ahc_tmode_lstate *pending_device;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Card characteristics
|
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
ahc_chip chip;
|
|
|
|
ahc_feature features;
|
|
|
|
ahc_bug bugs;
|
|
|
|
ahc_flag flags;
|
2002-08-31 06:42:10 +00:00
|
|
|
struct seeprom_config *seep_config;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
/* Values to store in the SEQCTL register for pause and unpause */
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t unpause;
|
|
|
|
uint8_t pause;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
/* Command Queues */
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t qoutfifonext;
|
|
|
|
uint8_t qinfifonext;
|
|
|
|
uint8_t *qoutfifo;
|
|
|
|
uint8_t *qinfifo;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-10-05 04:24:14 +00:00
|
|
|
/* Critical Section Data */
|
|
|
|
struct cs *critical_sections;
|
|
|
|
u_int num_critical_sections;
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/* Links for chaining softcs */
|
|
|
|
TAILQ_ENTRY(ahc_softc) links;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
/* Channel Names ('A', 'B', etc.) */
|
2000-09-16 20:02:28 +00:00
|
|
|
char channel;
|
|
|
|
char channel_b;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
/* Initiator Bus ID */
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t our_id;
|
|
|
|
uint8_t our_id_b;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
/*
|
2000-09-16 20:02:28 +00:00
|
|
|
* PCI error detection.
|
1998-09-15 07:24:17 +00:00
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
int unsolicited_ints;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
1998-11-23 01:33:47 +00:00
|
|
|
/*
|
|
|
|
* Target incoming command FIFO.
|
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
struct target_cmd *targetcmds;
|
|
|
|
uint8_t tqinfifonext;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Incoming and outgoing message handling.
|
|
|
|
*/
|
2000-09-16 20:02:28 +00:00
|
|
|
uint8_t send_msg_perror;
|
|
|
|
ahc_msg_type msg_type;
|
2000-09-22 22:18:05 +00:00
|
|
|
uint8_t msgout_buf[12];/* Message we are sending */
|
|
|
|
uint8_t msgin_buf[12];/* Message we are receiving */
|
2000-09-16 20:02:28 +00:00
|
|
|
u_int msgout_len; /* Length of message to send */
|
|
|
|
u_int msgout_index; /* Current index in msgout */
|
|
|
|
u_int msgin_index; /* Current index in msgin */
|
1999-04-23 23:27:31 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Mapping information for data structures shared
|
|
|
|
* between the sequencer and kernel.
|
|
|
|
*/
|
|
|
|
bus_dma_tag_t parent_dmat;
|
|
|
|
bus_dma_tag_t shared_data_dmat;
|
|
|
|
bus_dmamap_t shared_data_dmamap;
|
|
|
|
bus_addr_t shared_data_busaddr;
|
1999-01-14 06:14:15 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/*
|
|
|
|
* Bus address of the one byte buffer used to
|
|
|
|
* work-around a DMA bug for chips <= aic7880
|
|
|
|
* in target mode.
|
|
|
|
*/
|
|
|
|
bus_addr_t dma_bug_buf;
|
1999-08-16 22:49:29 +00:00
|
|
|
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
/* Information saved through suspend/resume cycles */
|
|
|
|
struct ahc_suspend_state suspend_state;
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/* Number of enabled target mode device on this card */
|
|
|
|
u_int enabled_luns;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/* Initialization level of this data structure */
|
|
|
|
u_int init_level;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/* PCI cacheline size. */
|
|
|
|
u_int pci_cachesize;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/* Per-Unit descriptive information */
|
|
|
|
const char *description;
|
|
|
|
char *name;
|
|
|
|
int unit;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2001-01-05 19:15:37 +00:00
|
|
|
/* Selection Timer settings */
|
|
|
|
int seltime;
|
|
|
|
int seltime_b;
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
uint16_t user_discenable;/* Disconnection allowed */
|
|
|
|
uint16_t user_tagenable;/* Tagged Queuing allowed */
|
|
|
|
};
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
TAILQ_HEAD(ahc_softc_tailq, ahc_softc);
|
|
|
|
extern struct ahc_softc_tailq ahc_tailq;
|
1998-09-15 07:24:17 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/************************ Active Device Information ***************************/
|
|
|
|
typedef enum {
|
|
|
|
ROLE_UNKNOWN,
|
|
|
|
ROLE_INITIATOR,
|
|
|
|
ROLE_TARGET
|
|
|
|
} role_t;
|
|
|
|
|
|
|
|
struct ahc_devinfo {
|
|
|
|
int our_scsiid;
|
|
|
|
int target_offset;
|
|
|
|
uint16_t target_mask;
|
|
|
|
u_int target;
|
|
|
|
u_int lun;
|
|
|
|
char channel;
|
|
|
|
role_t role; /*
|
|
|
|
* Only guaranteed to be correct if not
|
|
|
|
* in the busfree state.
|
|
|
|
*/
|
|
|
|
};
|
2000-07-18 20:12:14 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/****************************** PCI Structures ********************************/
|
2001-07-18 21:39:48 +00:00
|
|
|
typedef int (ahc_device_setup_t)(struct ahc_softc *);
|
2000-07-18 20:12:14 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
struct ahc_pci_identity {
|
|
|
|
uint64_t full_id;
|
|
|
|
uint64_t id_mask;
|
|
|
|
char *name;
|
|
|
|
ahc_device_setup_t *setup;
|
|
|
|
};
|
|
|
|
extern struct ahc_pci_identity ahc_pci_ident_table [];
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
extern const u_int ahc_num_pci_devs;
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
/***************************** VL/EISA Declarations ***************************/
|
|
|
|
struct aic7770_identity {
|
|
|
|
uint32_t full_id;
|
|
|
|
uint32_t id_mask;
|
|
|
|
char *name;
|
|
|
|
ahc_device_setup_t *setup;
|
|
|
|
};
|
|
|
|
extern struct aic7770_identity aic7770_ident_table [];
|
|
|
|
extern const int ahc_num_aic7770_devs;
|
|
|
|
|
|
|
|
#define AHC_EISA_SLOT_OFFSET 0xc00
|
|
|
|
#define AHC_EISA_IOSIZE 0x100
|
|
|
|
|
|
|
|
/*************************** Function Declarations ****************************/
|
|
|
|
/******************************************************************************/
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
u_int ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl);
|
|
|
|
void ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl);
|
|
|
|
void ahc_busy_tcl(struct ahc_softc *ahc,
|
|
|
|
u_int tcl, u_int busyid);
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
/***************************** PCI Front End *********************************/
|
|
|
|
struct ahc_pci_identity *ahc_find_pci_device(ahc_dev_softc_t);
|
|
|
|
int ahc_pci_config(struct ahc_softc *,
|
|
|
|
struct ahc_pci_identity *);
|
|
|
|
|
|
|
|
/*************************** EISA/VL Front End ********************************/
|
|
|
|
struct aic7770_identity *aic7770_find_device(uint32_t);
|
|
|
|
int aic7770_config(struct ahc_softc *ahc,
|
2002-04-24 16:58:51 +00:00
|
|
|
struct aic7770_identity *,
|
|
|
|
u_int port);
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
/************************** SCB and SCB queue management **********************/
|
|
|
|
int ahc_probe_scbs(struct ahc_softc *);
|
|
|
|
void ahc_run_untagged_queues(struct ahc_softc *ahc);
|
|
|
|
void ahc_run_untagged_queue(struct ahc_softc *ahc,
|
|
|
|
struct scb_tailq *queue);
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
void ahc_qinfifo_requeue_tail(struct ahc_softc *ahc,
|
|
|
|
struct scb *scb);
|
|
|
|
int ahc_match_scb(struct ahc_softc *ahc, struct scb *scb,
|
|
|
|
int target, char channel, int lun,
|
|
|
|
u_int tag, role_t role);
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
/****************************** Initialization ********************************/
|
|
|
|
struct ahc_softc *ahc_alloc(void *platform_arg, char *name);
|
2001-07-18 21:39:48 +00:00
|
|
|
int ahc_softc_init(struct ahc_softc *);
|
2000-09-16 20:02:28 +00:00
|
|
|
void ahc_controller_info(struct ahc_softc *ahc, char *buf);
|
|
|
|
int ahc_init(struct ahc_softc *ahc);
|
2001-03-29 00:36:35 +00:00
|
|
|
void ahc_intr_enable(struct ahc_softc *ahc, int enable);
|
ahc_eisa.c:
ahc_pci.c:
Add detach support.
Make use of soft allocated on our behalf by newbus.
For PCI devices, disable the mapping type we aren't
using for extra protection from rogue code.
aic7xxx_93cx6.c:
aic7xxx_93cx6.h:
Sync perforce IDs.
aic7xxx_freebsd.c:
Capture the eventhandle returned by EVENTHANDER_REGISTER
so we can kill the handler off during detach.
Use AHC_* constants instead of hard coded numbers in a
few more places.
Test PPR option state when deciding to "really" negotiate
when the CAM_NEGOTIATE flag is passed in a CCB.
Make use of core "ahc_pause_and_flushwork" routine in our
timeout handler rather than re-inventing this code.
Cleanup all of our resources (really!) in ahc_platform_free().
We should be all set to become a module now.
Implement the core ahc_detach() routine shared by all of
the FreeBSD front-ends.
aic7xxx_freebsd.h:
Softc storage for our event handler.
Null implementation for the ahc_platform_flushwork() OSM
callback. FreeBSD doesn't need this as XPT callbacks are
safe from all contexts and are done directly in ahc_done().
aic7xxx_inline.h:
Implement new lazy interrupt scheme. To avoid an extra
PCI bus read, we first check our completion queues to
see if any work has completed. If work is available, we
assume that this is the source of the interrupt and skip
reading INTSTAT. Any remaining interrupt status will be
cleared by a second call to the interrupt handler should
the interrupt line still be asserted. This drops the
interrupt handler down to a single PCI bus read in the
common case of I/O completion. This is the same overhead
as in the not so distant past, but the extra sanity of
perforning a PCI read after clearing the command complete
interrupt and before running the completion queue to avoid
missing command complete interrupts added a cycle.
aic7xxx.c:
During initialization, be sure to initialize all scratch
ram locations before they are read to avoid parity errors.
In this case, we use a new function, ahc_unbusy_tcl() to
initialize the scratch ram busy target table.
Replace instances of ahc_index_busy_tcl() used to unbusy
a tcl without looking at the old value with ahc_unbusy_tcl().
Modify ahc_sent_msg so that it can find single byte messages.
ahc_sent_msg is now used to determine if a transfer negotiation
attempt resulted in a bus free.
Be more careful in filtering out only the SCSI interrupts
of interest in ahc_handle_scsiint.
Rearrange interrupt clearing code to ensure that at least
one PCI transaction occurrs after hitting CLRSINT1 and
writting to CLRINT. CLRSINT1 writes take a bit to
take effect, and the re-arrangement provides sufficient
delay to ensure the write to CLRINT is effective. The
old code might report a spurious interrupt on some "fast"
chipsets.
export ahc-update_target_msg_request for use by OSM code.
If a target does not respond to our ATN request, clear
it once we move to a non-message phase. This avoids
sending a MSG_NOOP in some later message out phase.
Use max lun and max target constants instead of
hard-coded values.
Use softc storage built into our device_t under FreeBSD.
Fix a bug in ahc_free() that caused us to delete
resources that were not allocated.
Clean up any tstate/lstate info in ahc_free().
Clear the powerdown state in ahc_reset() so that
registers can be accessed.
Add a preliminary function for pausing the chip and
processing any posted work.
Add a preliminary suspend and resume functions.
aic7xxx.h:
Limit the number of supported luns to 64. We don't
support information unit transfers, so this is the
maximum that makes sense for these chips.
Add a new flag AHC_ALL_INTERRUPTS that forces the
processing of all interrupt state in a single invokation
of ahc_intr(). When the flag is not set, we use the
lazy interrupt handling scheme.
Add data structures to store controller state while
we are suspended.
Use constants instead of hard coded values where appropriate.
Correct some harmless "unsigned/signed" conflicts.
aic7xxx.seq:
Only perform the SCSIBUSL fix on ULTRA2 or newer controllers.
Older controllers seem to be confused by this.
In target mode, ignore PHASEMIS during data phases.
This bit seems to be flakey on U160 controllers acting
in target mode.
aic7xxx_pci.c:
Add support for the 29160C CPCI adapter.
Add definitions for subvendor ID information
available for devices with the "9005" vendor id.
We currently use this information to determine
if a multi-function device doesn't have the second
channel hooked up on a board.
Add rudimentary power mode code so we can put the
controller into the D0 state. In the future this
will be an OSM callback so that in FreeBSD we don't
duplicate functionality provided by the PCI code.
The powerstate code was added after I'd completed
my regression tests on this code.
Only capture "left over BIOS state" if the POWRDN
setting is not set in HCNTRL.
In target mode, don't bother sending incremental
CRC data.
2000-12-20 01:11:37 +00:00
|
|
|
void ahc_pause_and_flushwork(struct ahc_softc *ahc);
|
|
|
|
int ahc_suspend(struct ahc_softc *ahc);
|
|
|
|
int ahc_resume(struct ahc_softc *ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
void ahc_softc_insert(struct ahc_softc *);
|
2002-04-24 16:58:51 +00:00
|
|
|
struct ahc_softc *ahc_find_softc(struct ahc_softc *ahc);
|
2000-09-16 20:02:28 +00:00
|
|
|
void ahc_set_unit(struct ahc_softc *, int);
|
|
|
|
void ahc_set_name(struct ahc_softc *, char *);
|
|
|
|
void ahc_alloc_scbs(struct ahc_softc *ahc);
|
|
|
|
void ahc_free(struct ahc_softc *ahc);
|
|
|
|
int ahc_reset(struct ahc_softc *ahc);
|
|
|
|
void ahc_shutdown(void *arg);
|
|
|
|
|
|
|
|
/*************************** Interrupt Services *******************************/
|
|
|
|
void ahc_pci_intr(struct ahc_softc *ahc);
|
|
|
|
void ahc_clear_intstat(struct ahc_softc *ahc);
|
|
|
|
void ahc_run_qoutfifo(struct ahc_softc *ahc);
|
|
|
|
#ifdef AHC_TARGET_MODE
|
|
|
|
void ahc_run_tqinfifo(struct ahc_softc *ahc, int paused);
|
|
|
|
#endif
|
|
|
|
void ahc_handle_brkadrint(struct ahc_softc *ahc);
|
|
|
|
void ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat);
|
|
|
|
void ahc_handle_scsiint(struct ahc_softc *ahc,
|
|
|
|
u_int intstat);
|
2000-10-05 04:24:14 +00:00
|
|
|
void ahc_clear_critical_section(struct ahc_softc *ahc);
|
1999-12-06 18:23:31 +00:00
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
/***************************** Error Recovery *********************************/
|
|
|
|
typedef enum {
|
|
|
|
SEARCH_COMPLETE,
|
|
|
|
SEARCH_COUNT,
|
|
|
|
SEARCH_REMOVE
|
|
|
|
} ahc_search_action;
|
|
|
|
int ahc_search_qinfifo(struct ahc_softc *ahc, int target,
|
|
|
|
char channel, int lun, u_int tag,
|
|
|
|
role_t role, uint32_t status,
|
|
|
|
ahc_search_action action);
|
2002-08-31 06:42:10 +00:00
|
|
|
int ahc_search_untagged_queues(struct ahc_softc *ahc,
|
|
|
|
ahc_io_ctx_t ctx,
|
|
|
|
int target, char channel,
|
|
|
|
int lun, uint32_t status,
|
|
|
|
ahc_search_action action);
|
2000-09-16 20:02:28 +00:00
|
|
|
int ahc_search_disc_list(struct ahc_softc *ahc, int target,
|
|
|
|
char channel, int lun, u_int tag,
|
|
|
|
int stop_on_first, int remove,
|
|
|
|
int save_state);
|
|
|
|
void ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
|
|
|
|
int ahc_reset_channel(struct ahc_softc *ahc, char channel,
|
|
|
|
int initiate_reset);
|
2002-04-24 16:58:51 +00:00
|
|
|
int ahc_abort_scbs(struct ahc_softc *ahc, int target,
|
|
|
|
char channel, int lun, u_int tag,
|
|
|
|
role_t role, uint32_t status);
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
void ahc_restart(struct ahc_softc *ahc);
|
2002-04-24 16:58:51 +00:00
|
|
|
void ahc_calc_residual(struct ahc_softc *ahc,
|
|
|
|
struct scb *scb);
|
2000-09-16 20:02:28 +00:00
|
|
|
/*************************** Utility Functions ********************************/
|
This is an MFC candidate.
ahc_eisa.c:
Change aic7770_map_int to take an additional irq parameter.
Although we can get the irq from the eisa dev under FreeBSD,
we can't do this under linux, so the OSM interface must supply
this.
ahc_pci.c:
Move ahc_power_state_change() to the OSM. This allows us to
use a platform supplied function that does the same thing.
-current will move to the FreeBSD native API in the near
future.
aic7770.c:
Sync up with core changes to support Linux EISA.
We now store a 2 bit primary channel number rather
than a bit flag that only allows b to be the primary
channel. Adjust for this change.
aic7xxx.c:
Namespace and staticization cleanup. All exported symbols
use an "ahc_" prefix to avoid collisions with other modules.
Correct a logic bug that prevented us from dropping
ATN during some exceptional conditions during message
processing.
Take advantage of a new flag managed by the sequencer
that indicates if an SCB fetch is in progress. If so,
the currently selected SCB needs to be returned to the
free list to prevent an SCB leak. This leak is a rarity
and would only occur if a bus reset or timeout resulting
in a bus reset occurred in the middle of an SCB fetch.
Don't attempt to perform ULTRA transfers on ultra capable
adapters missing the external precision resistor required
for ultra speeds. I've never encountered an adapter
configured this way, but better safe than sorry.
Handle the case of 5MHz user sync rate set as "0" instead of 0x1c
in scratch ram.
If we lookup a period of 0 in our table (async), clear the scsi offset.
aic7xxx.h:
Adjust for the primary channel being represented as
a 2 bit integer in the flags member of the ahc softc.
Cleanup the flags definitions so that comment blocks are
not cramped.
Update seeprom definitions to correctly reflect the fact
that the primary channel is represented as a 2 bit integer.
Add AHC_ULTRA_DIASABLED softc flag to denote controllers
missing the external precision resistor.
aic7xxx.reg:
Add DFCACHETH to the definition of DFSTATUS for completness sake.
Add SEQ_FLAGS2 which currently only contains the SCB_DMA
(SCB DMA in progress) flag.
aic7xxx.seq:
Correct a problem when one lun has a disconnected untagged
transaction and another lun has disconnected tagged transactions.
Just because an entry is found in the untagged table doesn't
mean that it will match. If the match on the lun fails, cleanup
the SCB (return it to the disconnected list or free it), and snoop
for a tag message. Before this change, we reported an unsolicited
reselection. This bug was introduced about a month ago during an
overly aggressive optimization pass on the reselection code.
When cleaning up an SCB, we can't just blindly free the SCB. In
the paging case, if the SCB came off of the disconnected list, its
state may never have been updated in host memory. So, check the
disconnected bit in SCB_CONTROL and return the SCB to the disconnected
list if appropriate.
Manage the SCB_DMA flag of SEQ_FLAGS2.
More carefully shutdown the S/G dma engine in all cases by using
a subroutine. Supposedly not doing this can cause an arbiter hang
on some ULTRA2 chips.
Formatting cleanup.
On some chips, at least the aic7856, the transition from
MREQPEND to HDONE can take a full 4 clock cycles. Test
HDONE one more time to avoid this race. We only want our
FIFO hung recovery code to execute when the engine is
really hung.
aic7xxx_93cx6.c:
Sync perforce ids.
aic7xxx_freebsd.c:
Adjust for the primary channel being a 2 bit integer
rather than a flag for 'B' channel being the primary.
Namespace cleanup.
Unpause the sequencer in one error recovery path that
neglected to do so. This could have caused us to perform
a bus reset when a recovery message might have otherwise been
successful.
aic7xxx_freebsd.h:
Use AHC_PCI_CONFIG for controlling compilation of PCI
support consistently throughout the driver.
Move ahc_power_state_change() to OSM.
aic7xxx_inline.h
Namespace cleanup.
Adjust our interrupt handler so it will work in the edge
interrupt case. We must process all interrupt sources
when the interrupt fires or risk not ever getting an
interrupt again. This involves marking the fact
that we are relying on an edge interrupt in ahc->flags
and checking for this condition in addition to the
AHC_ALL_INTERRUPTS flag. This fixes hangs on the
284X and any other aic7770 installation where level
interrupts are not available.
aic7xxx_pci.c:
Move the powerstate manipulation code into the OSM. Several
OSes now provide this functionality natively.
Take another shot at using the data stored in scratch ram
if the SCB2 signature is correct and no SEEPROM data is
available. In the past this failed if external SCB ram
was configured because the memory port was locked. We
now release the memory port prior to testing the values
in SCB2 and re-acquire it prior to doing termination control.
Adjust for new 2 bit primary channel setting.
Trust the STPWLEVEL setting on v 3.X BIOSes too.
Configure any 785X ID in the same fashion and assume
that any device with a rev id of 1 or higher has the
PCI 2.1 retry bug.
2001-03-11 06:34:17 +00:00
|
|
|
struct ahc_phase_table_entry*
|
|
|
|
ahc_lookup_phase_entry(int phase);
|
2000-09-16 20:02:28 +00:00
|
|
|
void ahc_compile_devinfo(struct ahc_devinfo *devinfo,
|
|
|
|
u_int our_id, u_int target,
|
|
|
|
u_int lun, char channel,
|
|
|
|
role_t role);
|
|
|
|
/************************** Transfer Negotiation ******************************/
|
|
|
|
struct ahc_syncrate* ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
|
|
|
|
u_int *ppr_options, u_int maxsync);
|
|
|
|
u_int ahc_find_period(struct ahc_softc *ahc,
|
|
|
|
u_int scsirate, u_int maxsync);
|
|
|
|
void ahc_validate_offset(struct ahc_softc *ahc,
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
struct ahc_initiator_tinfo *tinfo,
|
2000-09-16 20:02:28 +00:00
|
|
|
struct ahc_syncrate *syncrate,
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
u_int *offset, int wide,
|
|
|
|
role_t role);
|
2000-09-16 20:02:28 +00:00
|
|
|
void ahc_validate_width(struct ahc_softc *ahc,
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
struct ahc_initiator_tinfo *tinfo,
|
|
|
|
u_int *bus_width,
|
|
|
|
role_t role);
|
2001-03-29 00:36:35 +00:00
|
|
|
int ahc_update_neg_request(struct ahc_softc*,
|
|
|
|
struct ahc_devinfo*,
|
|
|
|
struct ahc_tmode_tstate*,
|
|
|
|
struct ahc_initiator_tinfo*,
|
|
|
|
int /*force*/);
|
2000-09-16 20:02:28 +00:00
|
|
|
void ahc_set_width(struct ahc_softc *ahc,
|
|
|
|
struct ahc_devinfo *devinfo,
|
|
|
|
u_int width, u_int type, int paused);
|
|
|
|
void ahc_set_syncrate(struct ahc_softc *ahc,
|
|
|
|
struct ahc_devinfo *devinfo,
|
|
|
|
struct ahc_syncrate *syncrate,
|
|
|
|
u_int period, u_int offset,
|
|
|
|
u_int ppr_options,
|
|
|
|
u_int type, int paused);
|
2001-05-15 19:41:12 +00:00
|
|
|
typedef enum {
|
|
|
|
AHC_QUEUE_NONE,
|
|
|
|
AHC_QUEUE_BASIC,
|
|
|
|
AHC_QUEUE_TAGGED
|
|
|
|
} ahc_queue_alg;
|
|
|
|
|
2000-09-16 20:02:28 +00:00
|
|
|
void ahc_set_tags(struct ahc_softc *ahc,
|
2001-05-15 19:41:12 +00:00
|
|
|
struct ahc_devinfo *devinfo,
|
|
|
|
ahc_queue_alg alg);
|
2000-09-16 20:02:28 +00:00
|
|
|
|
|
|
|
/**************************** Target Mode *************************************/
|
|
|
|
#ifdef AHC_TARGET_MODE
|
|
|
|
void ahc_send_lstate_events(struct ahc_softc *,
|
2001-03-29 00:36:35 +00:00
|
|
|
struct ahc_tmode_lstate *);
|
2000-09-16 20:02:28 +00:00
|
|
|
void ahc_handle_en_lun(struct ahc_softc *ahc,
|
|
|
|
struct cam_sim *sim, union ccb *ccb);
|
|
|
|
cam_status ahc_find_tmode_devs(struct ahc_softc *ahc,
|
|
|
|
struct cam_sim *sim, union ccb *ccb,
|
2001-03-29 00:36:35 +00:00
|
|
|
struct ahc_tmode_tstate **tstate,
|
|
|
|
struct ahc_tmode_lstate **lstate,
|
2000-09-16 20:02:28 +00:00
|
|
|
int notfound_failure);
|
aic7xxx.c:
Filter incoming transfer negotiation requests to ensure they
never exceed the settings specified by the user.
In restart sequencer attempt to deal with a bug in the aic7895.
If a third party reset occurs at just the right time, the
stack register can lock up. When restarting the sequencer
after handling the SCSI reset, poke SEQADDR1 before resting
the sequencers program counter.
When something strange happens, dump the card's transaction
state via ahc_dump_card_state(). This should aid in debugging.
Handle request sense transactions via the QINFIFO instead of
attaching them to the waiting queue directly. The waiting
queue consumes card SCB resources and, in the pathological case
of every target on the bus beating our selection attemps and
issuing a check condition, could have caused us to run out
of SCBs. I have never seen this happen, and only early
cards with 3 or 4 SCBs had any real chance of ever getting
into this state.
Add additional sequencer interrupt codes to support firmware
diagnostics. The diagnostic code is enabled with the
AHC_DEBUG_SEQUENCER kernel option.
Make it possible to switch into and out of target mode on
the fly. The card comes up by default as an initiator but
will switch into target mode as soon as an enable lun operation
is performed. As always, target mode behavior is gated
by the AHC_TMODE_ENABLE kernel option so most users will
not be affected by this change.
In ahc_update_target_msg_request(), also issue a new
request if the ppr_options have changed.
Never issue a PPR as a target. It is forbidden by the spec.
Correct a bug in ahc_parse_msg() that prevented us from
responding to PPR messages as a target.
Mark SCBs that are on the untagged queue with a flag instead
of checking several fields in the SCB to see if the SCB should
be on the queue. This makes it easier for things like automatic
request sense requests to be queued without touching the
untagged queues even though they are untagged requests.
When dealing with ignore wide residue messages that occur
in the middle of a transfer, reset HADDR, not SHADDR for
non-ultra2 chips. Although SHADDR is where the firmware
fetches the ending transfer address for a save data pointers
request, it is readonly. Setting HADDR has the side effect
of also updating SHADDR.
Cleanup the output of ahc_dump_card_state() by nulling out the
free scb list in the non-paging case. The free list is only
used if we must page SCBs.
Correct the transmission of cdbs > 12 bytes in length. When
swapping HSCBs prior to notifing the sequencer of the new
transaction, the bus address pointer for the cdb must also
be recalculated to reflect its new location. We now defer
the calculation of the cdb address until just before queing
it to the card.
When pulling transfer negotiation settings out of scratch
ram, convert 5MHz/clock doubled settings to 10MHz.
Add a new function ahc_qinfifo_requeue_tail() for use by
error recovery actions and auto-request sense operations.
These operations always occur when the sequencer is paused,
so we can avoid the extra expense incurred in the normal
SCB queue method.
Use the BMOV instruction for all single byte moves on
controllers that support it. The bmov instruction is
twice as fast as an AND with an immediate of 0xFF as
is used on older controllers.
Correct a few bugs in ahc_dump_card_state(). If we have
hardware assisted queue registers, use them to get the
sequencer's idea of the head of the queue. When enumerating
the untagged queue, it helps to use the correct index for
the queue.
aic7xxx.h:
Indicate via a feature flag, which controllers can take
on both the target and the initiator role at the same time.
Add the AHC_SEQUENCER_DEBUG flag.
Add the SCB_CDB32_PTR flag used for dealing with cdbs
with lengths between 13 and 32 bytes.
Add new prototypes.
aic7xxx.reg:
Allow the SCSIBUSL register to be written to. This is
required to fix a selection timeout problem on the 7892/99.
Cleanup the sequencer interrupt codes so that all debugging
codes are grouped at the end of the list.
Correct the definition of the ULTRA_ENB and DISC_DSB locations
in scratch ram. This prevented the driver from properly honoring
these settings when no serial eeprom was available.
Remove an unused sequencer flag.
aic7xxx.seq:
Just before a potential select-out, clear the SCSIBUSL
register. Occasionally, during a selection timeout, the
contents of the register may be presented on the bus,
causing much confusion.
Add sequencer diagnostic code to detect software and or
hardware bugs. The code attempts to verify most list
operations so any corruption is caught before it occurs.
We also track information about why a particular reconnection
request was rejected.
Don't clobber the digital REQ/ACK filter setting in SXFRCTL0
when clearing the channel.
Fix a target mode bug that would cause us to return busy
status instead of queue full in respnse to a tagged transaction.
Cleanup the overrun case. It turns out that by simply
butting the chip in bitbucket mode, it will ack any
bytes until the phase changes. This drasticaly simplifies
things.
Prior to leaving the data phase, make sure that the S/G
preload queue is empty.
Remove code to place a request sense request on the waiting
queue. This is all handled by the kernel now.
Change the semantics of "findSCB". In the past, findSCB
ensured that a freshly paged in SCB appeared on the disconnected
list. The problem with this is that there is no guarantee that
the paged in SCB is for a disconnected transation. We now
defer any list manipulation to the caller who usually discards
the SCB via the free list.
Inline some busy target table operations.
Add a critical section to protect adding an SCB to
the disconnected list.
aic7xxx_freebsd.c:
Handle changes in the transfer negotiation setting API
to filter incoming requests. No filtering is necessary
for "goal" requests from the XPT.
Set the SCB_CDB32_PTR flag when queing a transaction with
a large cdb.
In ahc_timeout, only take action if the active SCB is
the timedout SCB. This deals with the case of two
transactions to the same device with different timeout
values.
Use ahc_qinfifo_requeu_tail() instead of home grown
version.
aic7xxx_inline.h:
Honor SCB_CDB32_PTR when queuing a new request.
aic7xxx_pci.c:
Use the maximum data fifo threshold for all chips.
2000-10-31 18:43:29 +00:00
|
|
|
#ifndef AHC_TMODE_ENABLE
|
|
|
|
#define AHC_TMODE_ENABLE 0
|
|
|
|
#endif
|
2000-09-16 20:02:28 +00:00
|
|
|
#endif
|
|
|
|
/******************************* Debug ***************************************/
|
2002-04-24 16:58:51 +00:00
|
|
|
#ifdef AHC_DEBUG
|
2002-08-31 06:42:10 +00:00
|
|
|
extern uint32_t ahc_debug;
|
|
|
|
#define AHC_SHOW_MISC 0x0001
|
|
|
|
#define AHC_SHOW_SENSE 0x0002
|
|
|
|
#define AHC_DUMP_SEEPROM 0x0004
|
|
|
|
#define AHC_SHOW_TERMCTL 0x0008
|
|
|
|
#define AHC_SHOW_MEMORY 0x0010
|
|
|
|
#define AHC_SHOW_MESSAGES 0x0020
|
|
|
|
#define AHC_SHOW_SELTO 0x0080
|
|
|
|
#define AHC_SHOW_QFULL 0x0200
|
|
|
|
#define AHC_SHOW_QUEUE 0x0400
|
|
|
|
#define AHC_SHOW_TQIN 0x0800
|
|
|
|
#define AHC_DEBUG_SEQUENCER 0x1000
|
2002-04-24 16:58:51 +00:00
|
|
|
#endif
|
2000-09-16 20:02:28 +00:00
|
|
|
void ahc_print_scb(struct scb *scb);
|
|
|
|
void ahc_dump_card_state(struct ahc_softc *ahc);
|
2002-08-31 06:42:10 +00:00
|
|
|
int ahc_print_register(ahc_reg_parse_entry_t *table,
|
|
|
|
u_int num_entries,
|
|
|
|
const char *name,
|
|
|
|
u_int address,
|
|
|
|
u_int value,
|
|
|
|
u_int *cur_column,
|
|
|
|
u_int wrap_point);
|
2002-04-24 16:58:51 +00:00
|
|
|
/******************************* SEEPROM *************************************/
|
|
|
|
int ahc_acquire_seeprom(struct ahc_softc *ahc,
|
|
|
|
struct seeprom_descriptor *sd);
|
|
|
|
void ahc_release_seeprom(struct seeprom_descriptor *sd);
|
2000-09-16 20:02:28 +00:00
|
|
|
#endif /* _AIC7XXX_H_ */
|