📄 aic7xxx.h
字号:
/* * Core definitions and data structures shareable across OS platforms. * * Copyright (c) 1994-2001 Justin T. Gibbs. * Copyright (c) 2000-2001 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#85 $ * * $FreeBSD$ */#ifndef _AIC7XXX_H_#define _AIC7XXX_H_/* Register Definitions */#include "aic7xxx_reg.h"/************************* Forward Declarations *******************************/struct ahc_platform_data;struct scb_platform_data;struct seeprom_descriptor;/****************************** Useful Macros *********************************/#ifndef MAX#define MAX(a,b) (((a) > (b)) ? (a) : (b))#endif#ifndef MIN#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 & LID)#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)))#ifdef AHC_DEBUG#define SCB_IS_SILENT(scb) \ ((ahc_debug & AHC_SHOW_MASKED_ERRORS) == 0 \ && (((scb)->flags & SCB_SILENT) != 0))#else#define SCB_IS_SILENT(scb) \ (((scb)->flags & SCB_SILENT) != 0)#endif#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))#ifndef AHC_TARGET_MODE#undef AHC_TMODE_ENABLE#define AHC_TMODE_ENABLE 0#endif/**************************** Driver Constants ********************************//* * The maximum number of supported targets. */#define AHC_NUM_TARGETS 16/* * The maximum number of supported luns. * 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. */#define AHC_NUM_LUNS 64/* * The maximum transfer per S/G segment. */#define AHC_MAXTRANSFER_SIZE 0x00ffffff /* limited by 24bit counter *//* * 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/* * 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 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 * precede it. */#define AHC_MAX_QUEUE 253/* * 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)/* * 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. */#define AHC_TMODE_CMDS 256/* Reset line assertion time in us */#define AHC_BUSRESET_DELAY 25/******************* 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, AHC_AIC7770 = 0x0001, AHC_AIC7850 = 0x0002, AHC_AIC7855 = 0x0003, AHC_AIC7859 = 0x0004, AHC_AIC7860 = 0x0005, AHC_AIC7870 = 0x0006, AHC_AIC7880 = 0x0007, AHC_AIC7895 = 0x0008, 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;/* * Features available in each chip type. */typedef enum { 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_TARGETMODE = 0x20000, /* Has tested target mode support */ AHC_MULTIROLE = 0x40000, /* Space for two roles at a time */ AHC_REMOVABLE = 0x80000, /* Hot-Swap supported */ AHC_AIC7770_FE = AHC_FENONE, /* * 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, AHC_AIC7870_FE = AHC_TARGETMODE|AHC_AUTOPAUSE, 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 |AHC_HS_MAILBOX|AHC_NEW_TERMCTL|AHC_LARGE_SCBS |AHC_TARGETMODE, 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, /* * 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_AUTOFLUSH_BUG = 0x02, /* * 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, /* * 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_PRIMARY_CHANNEL = 0x003, /* * The channel that should * be probed first. */ AHC_USEDEFAULTS = 0x004, /* * For cards without an seeprom * or a BIOS to initialize the chip's * SRAM, we use the default target * settings. */ 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, /* * Allow initiator operations on * this controller. */ AHC_TARGETROLE = 0x2000, /* * Allow target operations on this * controller. */ AHC_NEWEEPROM_FMT = 0x4000, AHC_TQINFIFO_BLOCKED = 0x10000, /* Blocked waiting for ATIOs */ AHC_INT50_SPEEDFLEX = 0x20000, /* * Internal 50pin connector * sits behind an aic3860 */ AHC_SCB_BTT = 0x40000, /* * The busy targets table is * stored in SCB space rather * than SRAM. */ AHC_BIOS_ENABLED = 0x80000, AHC_ALL_INTERRUPTS = 0x100000, 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. */ AHC_NO_BIOS_INIT = 0x8000000, /* No BIOS left over settings. */ AHC_DISABLE_PCI_PERR = 0x10000000, AHC_HAS_TERM_LOGIC = 0x20000000} ahc_flag;/************************* Hardware SCB Definition ***************************//* * The driver keeps up to MAX_SCB scb structures per card in memory. The SCB * consists of a "hardware SCB" mirroring the fields available on the card * and additional information the kernel stores for each transaction. * * 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 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 * still serve a different purpose than for the initiator role. See * 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; /* 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 { 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 */};struct hardware_scb {/*0*/ union { /* * 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; struct status_pkt status; 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 (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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -