summaryrefslogtreecommitdiffstats
path: root/sys/dev/aic7xxx/aic7xxx.h
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>2000-09-16 20:02:28 +0000
committergibbs <gibbs@FreeBSD.org>2000-09-16 20:02:28 +0000
commit7691c1f500299a3e38b674427e0f3818aa19c1de (patch)
treef52b2912a0a4e20093f8cf6d72ad047c59a00069 /sys/dev/aic7xxx/aic7xxx.h
parentb4ec565e1f9fb08395a52d9be1d736c5d8d4c175 (diff)
downloadFreeBSD-src-7691c1f500299a3e38b674427e0f3818aa19c1de.zip
FreeBSD-src-7691c1f500299a3e38b674427e0f3818aa19c1de.tar.gz
Move aicasm to its own subdirectory.
Separate our platform independent hooks from core driver functionality shared between platforms (FreeBSD and Linux at this time). Add sequencer workarounds for several chip->chipset interactions. Correct external SCB corruption problem on aic7895 based cards (3940AUW). Lots of cleanups resulting from the port to another OS.
Diffstat (limited to 'sys/dev/aic7xxx/aic7xxx.h')
-rw-r--r--sys/dev/aic7xxx/aic7xxx.h1010
1 files changed, 640 insertions, 370 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.h b/sys/dev/aic7xxx/aic7xxx.h
index c146a5b..09d71cb 100644
--- a/sys/dev/aic7xxx/aic7xxx.h
+++ b/sys/dev/aic7xxx/aic7xxx.h
@@ -1,7 +1,5 @@
/*
- * Interface to the generic driver for the aic7xxx based adaptec
- * SCSI controllers. This is used to implement product specific
- * probe and attach routines.
+ * Core definitions and data structures shareable across OS platforms.
*
* Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000 Justin T. Gibbs.
* All rights reserved.
@@ -30,17 +28,22 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $Id$
+ *
* $FreeBSD$
*/
#ifndef _AIC7XXX_H_
#define _AIC7XXX_H_
-#include "opt_aic7xxx.h" /* for config options */
+/* Register Definitions */
#include "aic7xxx_reg.h"
-#include <sys/bus.h> /* For device_t */
+/************************* Forward Declarations *******************************/
+struct ahc_platform_data;
+struct scb_platform_data;
+/****************************** Useful Macros *********************************/
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
@@ -49,6 +52,50 @@
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
+#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))
+
+/**************************** Driver Constants ********************************/
/*
* The maximum number of supported targets.
*/
@@ -56,9 +103,12 @@
/*
* The maximum number of supported luns.
- * The identify message supports up to 64 luns in SPI3.
+ * Although the identify message only supports 64 luns in SPI3, you
+ * can have 2^64 luns when information unit transfers are enabled.
+ * The max we can do sanely given the 8bit nature of the RISC engine
+ * on these chips is 256.
*/
-#define AHC_NUM_LUNS 64
+#define AHC_NUM_LUNS 256
/*
* The maximum transfer per S/G segment.
@@ -66,51 +116,30 @@
#define AHC_MAXTRANSFER_SIZE 0x00ffffff /* limited by 24bit counter */
/*
- * The number of dma segments supported. The sequencer can handle any number
- * of physically contiguous S/G entrys. To reduce the driver's memory
- * consumption, we limit the number supported to be sufficient to handle
- * the largest mapping supported by the kernel, MAXPHYS. Assuming the
- * transfer is as fragmented as possible and unaligned, this turns out to
- * be the number of paged sized transfers in MAXPHYS plus an extra element
- * to handle any unaligned residual. The sequencer fetches SG elements
- * in 128 byte chucks, so make the number per-transaction a nice multiple
- * of 16 (8 byte S/G elements).
- */
-/* XXX Worth the space??? */
-#define AHC_NSEG (roundup(btoc(MAXPHYS) + 1, 16))
-
-#define AHC_SCB_MAX 255 /*
- * Up to 255 SCBs on some types of aic7xxx
- * based boards. The aic7870 have 16 internal
- * SCBs, but external SRAM bumps this to 255.
- * The aic7770 family have only 4, and the
- * aic7850 has only 3.
- */
-
-#define AHC_TMODE_CMDS 256 /*
- * 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.
- */
+ * 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
+ * to 255 because of the 8bit nature of the RISC engine and the need to
+ * reserve the value of 255 as a "No Transaction" value.
+ */
+#define AHC_SCB_MAX 255
/*
- * The aic7xxx chips only support a 24bit length. We use the top
- * byte of the length to store additional address bits as well
- * as an indicator if this is the last SG segment in a 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.
+ * 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.
*/
-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
-};
+#define AHC_TMODE_CMDS 256
+
+/* Reset line assertion time in us */
+#define AHC_BUSRESET_DELAY 250
-/* The chip order is from least sophisticated to most sophisticated */
+/******************* Chip Characteristics/Operating Settings *****************/
+/*
+ * Chip Type
+ * The chip order is from least sophisticated to most sophisticated.
+ */
typedef enum {
AHC_NONE = 0x0000,
AHC_CHIPID_MASK = 0x00FF,
@@ -122,53 +151,59 @@ typedef enum {
AHC_AIC7870 = 0x0006,
AHC_AIC7880 = 0x0007,
AHC_AIC7895 = 0x0008,
- AHC_AIC7890 = 0x0009,
- AHC_AIC7896 = 0x000a,
- AHC_AIC7892 = 0x000b,
- AHC_AIC7899 = 0x000c,
+ AHC_AIC7895C = 0x0009,
+ AHC_AIC7890 = 0x000a,
+ AHC_AIC7896 = 0x000b,
+ AHC_AIC7892 = 0x000c,
+ AHC_AIC7899 = 0x000d,
AHC_VL = 0x0100, /* Bus type VL */
AHC_EISA = 0x0200, /* Bus type EISA */
AHC_PCI = 0x0400, /* Bus type PCI */
AHC_BUS_MASK = 0x0F00
} ahc_chip;
-extern char *ahc_chip_names[];
-
+/*
+ * Features available in each chip type.
+ */
typedef enum {
- AHC_FENONE = 0x0000,
- AHC_ULTRA = 0x0001, /* Supports 20MHz Transfers */
- AHC_ULTRA2 = 0x0002, /* Supports 40MHz Transfers */
- AHC_WIDE = 0x0004, /* Wide Channel */
- AHC_TWIN = 0x0008, /* Twin Channel */
- AHC_MORE_SRAM = 0x0010, /* 80 bytes instead of 64 */
- AHC_CMD_CHAN = 0x0020, /* Has a Command DMA Channel */
- AHC_QUEUE_REGS = 0x0040, /* Has Queue management registers */
- AHC_SG_PRELOAD = 0x0080, /* Can perform auto-SG preload */
- AHC_SPIOCAP = 0x0100, /* Has a Serial Port I/O Cap Register */
- AHC_MULTI_TID = 0x0200, /* Has bitmask of TIDs for select-in */
- AHC_HS_MAILBOX = 0x0400, /* Has HS_MAILBOX register */
- AHC_DT = 0x0800, /* Double Transition transfers */
- AHC_NEW_TERMCTL = 0x1000,
- AHC_MULTI_FUNC = 0x2000, /* Multi-Function Twin Channel Device */
- AHC_LARGE_SCBS = 0x4000, /* 64byte SCBs */
+ 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 */
AHC_AIC7770_FE = AHC_FENONE,
- AHC_AIC7850_FE = AHC_SPIOCAP,
+ AHC_AIC7850_FE = AHC_SPIOCAP|AHC_AUTOPAUSE,
AHC_AIC7855_FE = AHC_AIC7850_FE,
- AHC_AIC7859_FE = AHC_AIC7850_FE|AHC_ULTRA,
- AHC_AIC7860_FE = AHC_AIC7859_FE,
+ AHC_AIC7860_FE = AHC_AIC7850_FE|AHC_ULTRA,
AHC_AIC7870_FE = AHC_FENONE,
AHC_AIC7880_FE = AHC_ULTRA,
AHC_AIC7890_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA2|AHC_QUEUE_REGS
|AHC_SG_PRELOAD|AHC_MULTI_TID|AHC_HS_MAILBOX
|AHC_NEW_TERMCTL|AHC_LARGE_SCBS,
- AHC_AIC7892_FE = AHC_AIC7890_FE|AHC_DT,
- AHC_AIC7895_FE = AHC_AIC7880_FE|AHC_MORE_SRAM
+ AHC_AIC7892_FE = AHC_AIC7890_FE|AHC_DT|AHC_AUTORATE|AHC_AUTOPAUSE,
+ AHC_AIC7895_FE = AHC_AIC7880_FE|AHC_MORE_SRAM|AHC_AUTOPAUSE
|AHC_CMD_CHAN|AHC_MULTI_FUNC|AHC_LARGE_SCBS,
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
} ahc_feature;
+/*
+ * Bugs in the silicon that we work around in software.
+ */
typedef enum {
AHC_BUGNONE = 0x00,
/*
@@ -184,17 +219,38 @@ typedef enum {
*/
AHC_AUTOFLUSH_BUG = 0x02,
/*
- * On the aic7890/91 Rev 0 chips, cacheline
- * streaming does not work.
+ * On many chips, cacheline streaming does not work.
*/
AHC_CACHETHEN_BUG = 0x04,
/*
* On the aic7896/97 chips, cacheline
* streaming must be enabled.
*/
- AHC_CACHETHEN_DIS_BUG = 0x08
+ 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
} ahc_bug;
+/*
+ * Configuration specific settings.
+ * The driver determines these settings by probing the
+ * chip/controller's configuration.
+ */
typedef enum {
AHC_FNONE = 0x000,
AHC_PAGESCBS = 0x001,/* Enable SCB paging */
@@ -232,13 +288,17 @@ typedef enum {
* Internal 50pin connector
* sits behind an aic3860
*/
- AHC_SCB_BTT = 0x40000 /*
+ AHC_SCB_BTT = 0x40000,/*
* The busy targets table is
* stored in SCB space rather
* than SRAM.
*/
+ AHC_BIOS_ENABLED = 0x80000
} ahc_flag;
+/*
+ * Controller Information composed at probe time.
+ */
struct ahc_probe_config {
const char *description;
char channel;
@@ -249,25 +309,7 @@ struct ahc_probe_config {
ahc_flag flags;
};
-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,
- SCB_RECOVERY_SCB = 0x0040,
- SCB_NEGOTIATE = 0x0080,
- SCB_ABORT = 0x1000,
- SCB_QUEUED_MSG = 0x2000,
- SCB_ACTIVE = 0x4000,
- SCB_TARGET_IMMEDIATE = 0x8000
-} scb_flag;
+/************************* Hardware SCB Definition ***************************/
/*
* The driver keeps up to MAX_SCB scb structures per card in memory. The SCB
@@ -277,7 +319,7 @@ typedef enum {
* 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
- * contains the SCSI cdb (or pointer to the cdb) to be executed. After
+ * contains the SCSI cdb (or a pointer to the cdb) to be executed. After
* 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
@@ -285,28 +327,35 @@ typedef enum {
* struct target_data for details.
*/
+/*
+ * 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).
+ */
struct status_pkt {
- uint32_t residual_datacnt;
- uint32_t residual_sg_ptr;
- uint8_t scsi_status;
+ 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 */
};
+/*
+ * Target mode version of the shared data SCB segment.
+ */
struct target_data {
- uint8_t target_phases;
- uint8_t data_phase;
- uint8_t scsi_status;
- uint8_t initiator_tag;
+ uint8_t target_phases; /* Bitmap of phases to execute */
+ uint8_t data_phase; /* Data-In or Data-Out */
+ uint8_t scsi_status; /* SCSI status to give to initiator */
+ uint8_t initiator_tag; /* Initiator's transaction tag */
};
struct hardware_scb {
-/*0*/ uint8_t control;
-/*1*/ uint8_t scsiid; /* what to load in the SCSIID register */
-/*2*/ uint8_t lun;
-/*3*/ uint8_t cdb_len;
-/*4*/ union {
+/*0*/ union {
/*
- * 12 bytes of cdb information only
- * used on chips with 32byte SCBs.
+ * 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.
*/
uint8_t cdb[12];
uint32_t cdb_ptr;
@@ -314,22 +363,25 @@ struct hardware_scb {
struct target_data tdata;
} shared_data;
/*
- * 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. If no transfer is to occur,
- * sgptr is set to SG_LIST_NULL. The SG_FULL_RESID flag insures 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 three is a residual in the tranfer,
- * it will set the SG_RESID_VALID flag in sgptr and dma the scb back into
+ * 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
* host memory. To sumarize:
*
* Sequencer:
@@ -347,58 +399,165 @@ struct hardware_scb {
* and so may point beyond the last valid sg entry for the
* transfer.
*/
-/*16*/ uint32_t dataptr;
-/*20*/ uint32_t datacnt; /*
- * The highest address byte is
- * really the 5th. byte in the
- * dataptr.
+/*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.
*/
-/*24*/ uint32_t sgptr;
+/*20*/ uint32_t sgptr;
#define SG_PTR_MASK 0xFFFFFFF8
-/*28*/ uint8_t tag; /* Index into our kernel SCB array.
+/*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.
* Also used as the tag for tagged I/O
*/
+/*28*/ uint8_t cdb_len;
/*29*/ uint8_t scsirate; /* Value for SCSIRATE register */
/*30*/ uint8_t scsioffset; /* Value for SCSIOFFSET register */
-/*31*/ uint8_t next; /* Used for threading SCBs in the
+/*31*/ uint8_t next; /*
+ * Used for threading SCBs in the
* "Waiting for Selection" and
* "Disconnected SCB" lists down
* in the sequencer.
*/
/*32*/ uint8_t cdb32[32]; /*
- * CDB storage for controllers
- * supporting 64 byte SCBs.
+ * 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.
*/
};
+/************************ 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
+};
+
+/*
+ * 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,
+ SCB_RECOVERY_SCB = 0x0040,
+ SCB_NEGOTIATE = 0x0080,
+ SCB_ABORT = 0x1000,
+ SCB_QUEUED_MSG = 0x2000,
+ SCB_ACTIVE = 0x4000,
+ SCB_TARGET_IMMEDIATE = 0x8000
+} scb_flag;
+
struct scb {
- struct hardware_scb *hscb;
+ struct hardware_scb *hscb;
union {
- SLIST_ENTRY(scb) sle;
- TAILQ_ENTRY(scb) tqe;
+ SLIST_ENTRY(scb) sle;
+ TAILQ_ENTRY(scb) tqe;
} links;
- union ccb *ccb; /* the ccb for this cmd */
- scb_flag flags;
- bus_dmamap_t dmamap;
- struct ahc_dma_seg *sg_list;
- bus_addr_t sg_list_phys;
- bus_addr_t cdb32_busaddr;
- u_int sg_count;/* How full ahc_dma_seg is */
+ LIST_ENTRY(scb) pending_links;
+ ahc_io_ctx_t io_ctx;
+ scb_flag flags;
+#ifndef __linux__
+ bus_dmamap_t dmamap;
+#endif
+ struct scb_platform_data *platform_data;
+ struct ahc_dma_seg *sg_list;
+ bus_addr_t sg_list_phys;
+ bus_addr_t cdb32_busaddr;
+ u_int sg_count;/* How full ahc_dma_seg is */
+};
+
+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;
+};
+
+struct scb_data {
+ struct hardware_scb *hscbs; /* Array of hardware SCBs */
+ struct scb *scbarray; /* Array of kernel SCBs */
+ SLIST_HEAD(, scb) free_scbs; /*
+ * Pool of SCBs ready to be assigned
+ * commands to execute.
+ */
+ 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.
+ */
};
+/************************ Target Mode Definitions *****************************/
+
/*
* Connection desciptor for select-in requests in target mode.
- * The first byte is the connecting target, followed by identify
- * message and optional tag information, terminated by 0xFF. The
- * remainder is the command to execute. The cmd_valid byte is on
- * an 8 byte boundary to simplify setting it on aic7880 hardware
- * which only has limited direct access to the DMA FIFO.
*/
struct target_cmd {
- uint8_t scsiid;
+ uint8_t scsiid; /* Our ID and the initiator's ID */
uint8_t identify; /* Identify message */
- uint8_t bytes[22];
- uint8_t cmd_valid;
+ 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.
+ */
uint8_t pad[7];
};
@@ -415,9 +574,13 @@ struct ahc_tmode_event {
};
/*
- * Per lun target mode state including accept TIO CCB
- * and immediate notify CCB pools.
+ * 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.
*/
+#ifdef AHC_TARGET_MODE
struct tmode_lstate {
struct cam_path *path;
struct ccb_hdr_slist accept_tios;
@@ -426,36 +589,46 @@ struct tmode_lstate {
uint8_t event_r_idx;
uint8_t event_w_idx;
};
+#else
+struct tmode_lstate;
+#endif
+/******************** Transfer Negotiation Datastructures *********************/
#define AHC_TRANS_CUR 0x01 /* Modify current neogtiation status */
-#define AHC_TRANS_ACTIVE 0x03 /* Assume this is the active target */
+#define AHC_TRANS_ACTIVE 0x03 /* Assume this target is on the bus */
#define AHC_TRANS_GOAL 0x04 /* Modify negotiation goal */
#define AHC_TRANS_USER 0x08 /* Modify user negotiation settings */
+/*
+ * Transfer Negotiation Information.
+ */
struct ahc_transinfo {
- uint8_t protocol_version;
- uint8_t transport_version;
- uint8_t width;
- uint8_t period;
- uint8_t offset;
- uint8_t ppr_options;
+ 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 */
};
+/*
+ * Per-initiator current, goal and user transfer negotiation information. */
struct ahc_initiator_tinfo {
- uint8_t scsirate;
+ uint8_t scsirate; /* Computed value for SCSIRATE reg */
struct ahc_transinfo current;
struct ahc_transinfo goal;
struct ahc_transinfo user;
};
/*
- * Per target mode enabled target state. Esentially just an array of
- * pointers to lun target state as well as sync/wide negotiation information
- * for each initiator<->target mapping (including the mapping for when we
- * are the initiator).
+ * 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.
*/
struct tmode_tstate {
- struct tmode_lstate* enabled_luns[64];
+ struct tmode_lstate* enabled_luns[64]; /* NULL == disabled */
struct ahc_initiator_tinfo transinfo[16];
/*
@@ -467,12 +640,65 @@ struct tmode_tstate {
};
/*
- * Define the format of the aic7XXX SEEPROM registers (16 bits).
+ * 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;
+};
+
+/*
+ * The synchronouse transfer rate table.
+ */
+extern struct ahc_syncrate ahc_syncrates[];
+
+/*
+ * Indexes into our table of syncronous transfer rates.
*/
+#define AHC_SYNCRATE_DT 0
+#define AHC_SYNCRATE_ULTRA2 1
+#define AHC_SYNCRATE_ULTRA 3
+#define AHC_SYNCRATE_FAST 6
+
+/***************************** Lookup Tables **********************************/
+/*
+ * Textual descriptions of the different chips indexed by chip type.
+ */
+extern char *ahc_chip_names[];
+extern const u_int num_chip_names;
+
+/*
+ * Hardware error codes.
+ */
+struct hard_error_entry {
+ uint8_t errno;
+ char *errmesg;
+};
+extern struct hard_error_entry hard_error[];
+extern const u_int num_errors;
+
+/*
+ * Phase -> name and message out response
+ * to parity errors in each phase table.
+ */
+struct phase_table_entry {
+ uint8_t phase;
+ uint8_t mesg_out; /* Message response to parity errors */
+ char *phasemsg;
+};
+extern struct phase_table_entry phase_table[];
+extern const u_int num_phases;
+
+/************************** Serial EEPROM Format ******************************/
struct seeprom_config {
/*
- * SCSI ID Configuration Flags
+ * Per SCSI ID Configuration Flags
*/
uint16_t device_flags[16]; /* words 0-15 */
#define CFXFER 0x0007 /* synchronous transfer rate */
@@ -525,7 +751,7 @@ struct seeprom_config {
#define CFDOMAINVAL 0x4000 /* Perform Domain Validation*/
/*
- * Bus Release, Host Adapter ID
+ * Bus Release Time, Host Adapter ID
*/
uint16_t brtime_id; /* word 18 */
#define CFSCSIID 0x000f /* host adapter SCSI ID */
@@ -545,17 +771,7 @@ struct seeprom_config {
uint16_t checksum; /* word 31 */
};
-struct ahc_syncrate {
- u_int sxfr_u2;
- u_int sxfr;
- /* Rates in Ultra mode have bit 8 of sxfr set */
-#define ULTRA_SXFR 0x100
-#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;
-};
-
+/**************************** Message Buffer *********************************/
typedef enum {
MSG_TYPE_NONE = 0x00,
MSG_TYPE_INITIATOR_MSGOUT = 0x01,
@@ -564,53 +780,27 @@ typedef enum {
MSG_TYPE_TARGET_MSGIN = 0x04
} ahc_msg_type;
-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;
-};
-
-struct scb_data {
- struct hardware_scb *hscbs; /* Array of hardware SCBs */
- struct scb *scbarray; /* Array of kernel SCBs */
- SLIST_HEAD(, scb) free_scbs; /*
- * Pool of SCBs ready to be assigned
- * commands to execute.
- */
- 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.
- */
-};
+typedef enum {
+ MSGLOOP_IN_PROG,
+ MSGLOOP_MSGCOMPLETE,
+ MSGLOOP_TERMINATED
+} msg_loop_stat;
+/*********************** Software Configuration Structure *********************/
TAILQ_HEAD(scb_tailq, scb);
struct ahc_softc {
- bus_space_tag_t tag;
- bus_space_handle_t bsh;
- bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
- struct scb_data *scb_data;
+ 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;
/*
- * CCBs that have been sent to the controller
+ * SCBs that have been sent to the controller
*/
- LIST_HEAD(, ccb_hdr) pending_ccbs;
+ LIST_HEAD(, scb) pending_scbs;
/*
* Counting lock for deferring the release of additional
@@ -618,7 +808,7 @@ struct ahc_softc {
* the lock is decremented to 0, all queues in the
* untagged_queues array are run.
*/
- u_int untagged_queue_lock;
+ u_int untagged_queue_lock;
/*
* Per-target queue of untagged-transactions. The
@@ -627,7 +817,17 @@ struct ahc_softc {
* target. The driver only allows a single untagged
* transaction per target.
*/
- struct scb_tailq untagged_queues[16];
+ struct scb_tailq untagged_queues[16];
+
+ /*
+ * Platform specific data.
+ */
+ struct ahc_platform_data *platform_data;
+
+ /*
+ * Platform specific device information.
+ */
+ ahc_dev_softc_t dev_softc;
/*
* Target mode related state kept on a per enabled lun basis.
@@ -635,193 +835,263 @@ struct ahc_softc {
* As an initiator, we keep one target entry for our initiator
* ID to store our sync/wide transfer settings.
*/
- struct tmode_tstate* enabled_targets[16];
+ struct tmode_tstate* enabled_targets[16];
/*
* The black hole device responsible for handling requests for
* disabled luns on enabled targets.
*/
- struct tmode_lstate* black_hole;
+ struct tmode_lstate* black_hole;
/*
* Device instance currently on the bus awaiting a continue TIO
* for a command that was not given the disconnect priveledge.
*/
- struct tmode_lstate* pending_device;
+ struct tmode_lstate* pending_device;
/*
* Card characteristics
*/
- ahc_chip chip;
- ahc_feature features;
- ahc_bug bugs;
- ahc_flag flags;
+ ahc_chip chip;
+ ahc_feature features;
+ ahc_bug bugs;
+ ahc_flag flags;
/* Values to store in the SEQCTL register for pause and unpause */
- uint8_t unpause;
- uint8_t pause;
+ uint8_t unpause;
+ uint8_t pause;
/* Command Queues */
- uint8_t qoutfifonext;
- uint8_t qinfifonext;
- uint8_t *qoutfifo;
- uint8_t *qinfifo;
-
- /*
- * Hooks into the XPT.
- */
- struct cam_sim *sim;
- struct cam_sim *sim_b;
- struct cam_path *path;
- struct cam_path *path_b;
+ uint8_t qoutfifonext;
+ uint8_t qinfifonext;
+ uint8_t *qoutfifo;
+ uint8_t *qinfifo;
- int unit;
+ /* Links for chaining softcs */
+ TAILQ_ENTRY(ahc_softc) links;
/* Channel Names ('A', 'B', etc.) */
- char channel;
- char channel_b;
+ char channel;
+ char channel_b;
/* Initiator Bus ID */
- uint8_t our_id;
- uint8_t our_id_b;
+ uint8_t our_id;
+ uint8_t our_id_b;
/* Targets that need negotiation messages */
- uint16_t targ_msg_req;
+ uint16_t targ_msg_req;
/*
- * PCI error detection and data for running the
- * PCI error interrupt handler.
+ * PCI error detection.
*/
- int unsolicited_ints;
- device_t device;
+ int unsolicited_ints;
/*
* Target incoming command FIFO.
*/
- struct target_cmd *targetcmds;
- uint8_t tqinfifonext;
+ struct target_cmd *targetcmds;
+ uint8_t tqinfifonext;
/*
* Incoming and outgoing message handling.
*/
- uint8_t send_msg_perror;
- ahc_msg_type msg_type;
- uint8_t msgout_buf[8]; /* Message we are sending */
- uint8_t msgin_buf[8]; /* Message we are receiving */
- 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 */
-
- int regs_res_type;
- int regs_res_id;
- int irq_res_type;
- struct resource *regs;
- struct resource *irq;
- void *ih;
- 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;
- bus_addr_t dma_bug_buf;
+ uint8_t send_msg_perror;
+ ahc_msg_type msg_type;
+ uint8_t msgout_buf[8];/* Message we are sending */
+ uint8_t msgin_buf[8]; /* Message we are receiving */
+ 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 */
- /* Number of enabled target mode device on this card */
- u_int enabled_luns;
+ /*
+ * 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;
- /* Initialization level of this data structure */
- u_int init_level;
+ /*
+ * 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;
- uint16_t user_discenable;/* Disconnection allowed */
- uint16_t user_tagenable;/* Tagged Queuing allowed */
-};
+ /* Number of enabled target mode device on this card */
+ u_int enabled_luns;
-struct full_ahc_softc {
- struct ahc_softc softc;
- struct scb_data scb_data_storage;
-};
+ /* Initialization level of this data structure */
+ u_int init_level;
-/* #define AHC_DEBUG */
-#ifdef AHC_DEBUG
-/* Different debugging levels used when AHC_DEBUG is defined */
-#define AHC_SHOWMISC 0x0001
-#define AHC_SHOWCMDS 0x0002
-#define AHC_SHOWSCBS 0x0004
-#define AHC_SHOWABORTS 0x0008
-#define AHC_SHOWSENSE 0x0010
-#define AHC_SHOWSCBCNT 0x0020
-
-extern int ahc_debug; /* Initialized in i386/scsi/aic7xxx.c */
-#endif
+ /* PCI cacheline size. */
+ u_int pci_cachesize;
-#define ahc_inb(ahc, port) \
- bus_space_read_1((ahc)->tag, (ahc)->bsh, port)
-
-#define ahc_outb(ahc, port, value) \
- bus_space_write_1((ahc)->tag, (ahc)->bsh, port, value)
-
-#define ahc_outsb(ahc, port, valp, count) \
- bus_space_write_multi_1((ahc)->tag, (ahc)->bsh, port, valp, count)
-
-#define ahc_insb(ahc, port, valp, count) \
- bus_space_read_multi_1((ahc)->tag, (ahc)->bsh, port, valp, count)
-
-char *ahc_name(struct ahc_softc *ahc);
-
-void ahc_init_probe_config(struct ahc_probe_config *config);
-struct ahc_softc*
- ahc_alloc(device_t dev, struct resource *regs, int regs_type,
- int regs_id, bus_dma_tag_t parent_dmat,
- struct ahc_probe_config *config, struct scb_data *scb_data);
-int ahc_reset(struct ahc_softc *ahc);
-void ahc_free(struct ahc_softc *);
-int ahc_probe_scbs(struct ahc_softc *);
-int ahc_init(struct ahc_softc *);
-int ahc_attach(struct ahc_softc *);
-void ahc_intr(void *arg);
-static __inline int sequencer_paused(struct ahc_softc *ahc);
-static __inline void ahc_pause_bug_fix(struct ahc_softc *ahc);
-static __inline void pause_sequencer(struct ahc_softc *ahc);
-static __inline void unpause_sequencer(struct ahc_softc *ahc);
-
-static __inline void
-ahc_pause_bug_fix(struct ahc_softc *ahc)
-{
- /*
- * Clear the CIOBUS stretch signal by reading a register that will
- * set this signal and deassert it. Without this workaround, if
- * the chip is paused, by an interrupt or manual pause, while
- * accessing scb ram, then accesses to certain registers will hang
- * the system (infinite pci retries).
- */
- if ((ahc->features & AHC_ULTRA2) != 0)
- (void)ahc_inb(ahc, CCSCBCTL);
-}
+ /* Per-Unit descriptive information */
+ const char *description;
+ char *name;
+ int unit;
-static __inline int
-sequencer_paused(struct ahc_softc *ahc)
-{
- return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0);
-}
+ uint16_t user_discenable;/* Disconnection allowed */
+ uint16_t user_tagenable;/* Tagged Queuing allowed */
+};
-static __inline void
-pause_sequencer(struct ahc_softc *ahc)
-{
- ahc_outb(ahc, HCNTRL, ahc->pause);
+TAILQ_HEAD(ahc_softc_tailq, ahc_softc);
+extern struct ahc_softc_tailq ahc_tailq;
- /*
- * Since the sequencer can disable pausing in a critical section, we
- * must loop until it actually stops.
- */
- while (sequencer_paused(ahc) == 0)
- ;
+/************************ 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.
+ */
+};
- ahc_pause_bug_fix(ahc);
-}
+/****************************** PCI Structures ********************************/
+typedef int (ahc_device_setup_t)(ahc_dev_softc_t,
+ struct ahc_probe_config *);
-static __inline void
-unpause_sequencer(struct ahc_softc *ahc)
-{
- if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0)
- ahc_outb(ahc, HCNTRL, ahc->unpause);
-}
+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 [];
+extern const int ahc_num_pci_devs;
+
+/***************************** 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 ****************************/
+/******************************************************************************/
+
+/***************************** 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,
+ struct aic7770_identity *);
+
+/************************** 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);
+
+/****************************** Initialization ********************************/
+void ahc_init_probe_config(struct ahc_probe_config *);
+struct ahc_softc *ahc_alloc(void *platform_arg, char *name);
+int ahc_softc_init(struct ahc_softc *,
+ struct ahc_probe_config*);
+void ahc_controller_info(struct ahc_softc *ahc, char *buf);
+int ahc_init(struct ahc_softc *ahc);
+void ahc_softc_insert(struct ahc_softc *);
+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);
-#endif /* _AIC7XXX_H_ */
+/***************************** 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);
+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);
+void restart_sequencer(struct ahc_softc *ahc);
+/*************************** Utility Functions ********************************/
+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,
+ struct ahc_syncrate *syncrate,
+ u_int *offset, int wide);
+void ahc_validate_width(struct ahc_softc *ahc,
+ u_int *bus_width);
+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);
+void ahc_set_tags(struct ahc_softc *ahc,
+ struct ahc_devinfo *devinfo, int enable);
+
+/**************************** Target Mode *************************************/
+#ifdef AHC_TARGET_MODE
+void ahc_send_lstate_events(struct ahc_softc *,
+ struct tmode_lstate *);
+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,
+ struct tmode_tstate **tstate,
+ struct tmode_lstate **lstate,
+ int notfound_failure);
+void ahc_setup_target_msgin(struct ahc_softc *ahc,
+ struct ahc_devinfo *devinfo);
+#endif
+/******************************* Debug ***************************************/
+void ahc_print_scb(struct scb *scb);
+void ahc_dump_card_state(struct ahc_softc *ahc);
+#endif /* _AIC7XXX_H_ */
OpenPOWER on IntegriCloud