1139749Simp/*- 240024Sgibbs * Definitions for low level routines and data structures 340024Sgibbs * for the Advanced Systems Inc. SCSI controllers chips. 440024Sgibbs * 556979Sgibbs * Copyright (c) 1998, 1999, 2000 Justin T. Gibbs. 640024Sgibbs * All rights reserved. 740024Sgibbs * 840024Sgibbs * Redistribution and use in source and binary forms, with or without 940024Sgibbs * modification, are permitted provided that the following conditions 1040024Sgibbs * are met: 1140024Sgibbs * 1. Redistributions of source code must retain the above copyright 1240024Sgibbs * notice, this list of conditions, and the following disclaimer, 1356979Sgibbs * without modification. 1440024Sgibbs * 2. Redistributions in binary form must reproduce the above copyright 1540024Sgibbs * notice, this list of conditions and the following disclaimer in the 1640024Sgibbs * documentation and/or other materials provided with the distribution. 1740024Sgibbs * 3. The name of the author may not be used to endorse or promote products 1840024Sgibbs * derived from this software without specific prior written permission. 1940024Sgibbs * 2040024Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2140024Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2240024Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2340024Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 2440024Sgibbs * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2540024Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2640024Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2740024Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2840024Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2940024Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3040024Sgibbs * SUCH DAMAGE. 3140024Sgibbs * 3250477Speter * $FreeBSD: releng/10.3/sys/dev/advansys/adwlib.h 241588 2012-10-15 15:26:00Z jhb $ 3340024Sgibbs */ 34141854Sobrien/*- 3540024Sgibbs * Ported from: 3640024Sgibbs * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters 3740024Sgibbs * 3840024Sgibbs * Copyright (c) 1995-1998 Advanced System Products, Inc. 3940024Sgibbs * All Rights Reserved. 4040024Sgibbs * 4140024Sgibbs * Redistribution and use in source and binary forms, with or without 4240024Sgibbs * modification, are permitted provided that redistributions of source 4340024Sgibbs * code retain the above copyright notice and this comment without 4440024Sgibbs * modification. 4540024Sgibbs */ 4640024Sgibbs 4740024Sgibbs#ifndef _ADWLIB_H_ 4840024Sgibbs#define _ADWLIB_H_ 4940024Sgibbs 5040024Sgibbs#include "opt_adw.h" 5140024Sgibbs 5240024Sgibbs#include <dev/advansys/adwmcode.h> 5340024Sgibbs 5440024Sgibbs#define ADW_DEF_MAX_HOST_QNG 253 5540024Sgibbs#define ADW_DEF_MIN_HOST_QNG 16 5640024Sgibbs#define ADW_DEF_MAX_DVC_QNG 63 5740024Sgibbs#define ADW_DEF_MIN_DVC_QNG 4 5840024Sgibbs 5940024Sgibbs#define ADW_MAX_TID 15 6040024Sgibbs#define ADW_MAX_LUN 7 6140024Sgibbs 6256979Sgibbs#define ADW_ALL_TARGETS 0xFFFF 6356979Sgibbs 6456979Sgibbs#define ADW_TARGET_GROUP(tid) ((tid) & ~0x3) 6556979Sgibbs#define ADW_TARGET_GROUP_SHIFT(tid) (((tid) & 0x3) * 4) 6656979Sgibbs#define ADW_TARGET_GROUP_MASK(tid) (0xF << ADW_TARGET_GROUP_SHIFT(tid)) 6756979Sgibbs 6840024Sgibbs/* 6940024Sgibbs * Board Register offsets. 7040024Sgibbs */ 7140024Sgibbs#define ADW_INTR_STATUS_REG 0x0000 7240024Sgibbs#define ADW_INTR_STATUS_INTRA 0x01 7340024Sgibbs#define ADW_INTR_STATUS_INTRB 0x02 7440024Sgibbs#define ADW_INTR_STATUS_INTRC 0x04 7556979Sgibbs#define ADW_INTR_STATUS_INTRALL 0x07 7640024Sgibbs 7740024Sgibbs 7840024Sgibbs#define ADW_SIGNATURE_WORD 0x0000 7940024Sgibbs#define ADW_CHIP_ID_WORD 0x04C1 8040024Sgibbs 8140024Sgibbs#define ADW_SIGNATURE_BYTE 0x0001 8240024Sgibbs#define ADW_CHIP_ID_BYTE 0x25 8340024Sgibbs 8440024Sgibbs#define ADW_INTR_ENABLES 0x0002 /*8 bit */ 8540024Sgibbs#define ADW_INTR_ENABLE_HOST_INTR 0x01 8640024Sgibbs#define ADW_INTR_ENABLE_SEL_INTR 0x02 8740024Sgibbs#define ADW_INTR_ENABLE_DPR_INTR 0x04 8840024Sgibbs#define ADW_INTR_ENABLE_RTA_INTR 0x08 8940024Sgibbs#define ADW_INTR_ENABLE_RMA_INTR 0x10 9040024Sgibbs#define ADW_INTR_ENABLE_RST_INTR 0x20 9140024Sgibbs#define ADW_INTR_ENABLE_DPE_INTR 0x40 9240024Sgibbs#define ADW_INTR_ENABLE_GLOBAL_INTR 0x80 9340024Sgibbs 9440024Sgibbs#define ADW_CTRL_REG 0x0002 /*16 bit*/ 9540024Sgibbs#define ADW_CTRL_REG_HOST_INTR 0x0100 9640024Sgibbs#define ADW_CTRL_REG_SEL_INTR 0x0200 9740024Sgibbs#define ADW_CTRL_REG_DPR_INTR 0x0400 9840024Sgibbs#define ADW_CTRL_REG_RTA_INTR 0x0800 9940024Sgibbs#define ADW_CTRL_REG_RMA_INTR 0x1000 10040024Sgibbs#define ADW_CTRL_REG_RES_BIT14 0x2000 10140024Sgibbs#define ADW_CTRL_REG_DPE_INTR 0x4000 10240024Sgibbs#define ADW_CTRL_REG_POWER_DONE 0x8000 10340024Sgibbs#define ADW_CTRL_REG_ANY_INTR 0xFF00 10440024Sgibbs#define ADW_CTRL_REG_CMD_RESET 0x00C6 10540024Sgibbs#define ADW_CTRL_REG_CMD_WR_IO_REG 0x00C5 10640024Sgibbs#define ADW_CTRL_REG_CMD_RD_IO_REG 0x00C4 10740024Sgibbs#define ADW_CTRL_REG_CMD_WR_PCI_CFG 0x00C3 10840024Sgibbs#define ADW_CTRL_REG_CMD_RD_PCI_CFG 0x00C2 10940024Sgibbs 11040024Sgibbs#define ADW_RAM_ADDR 0x0004 11140024Sgibbs#define ADW_RAM_DATA 0x0006 11240024Sgibbs 11340024Sgibbs#define ADW_RISC_CSR 0x000A 11440024Sgibbs#define ADW_RISC_CSR_STOP 0x0000 11540024Sgibbs#define ADW_RISC_TEST_COND 0x2000 11640024Sgibbs#define ADW_RISC_CSR_RUN 0x4000 11740024Sgibbs#define ADW_RISC_CSR_SINGLE_STEP 0x8000 11840024Sgibbs 11940024Sgibbs#define ADW_SCSI_CFG0 0x000C 12040024Sgibbs#define ADW_SCSI_CFG0_TIMER_MODEAB 0xC000 /* 12140024Sgibbs * Watchdog, Second, 12240024Sgibbs * and Selto timer CFG 12340024Sgibbs */ 12440024Sgibbs#define ADW_SCSI_CFG0_PARITY_EN 0x2000 12540024Sgibbs#define ADW_SCSI_CFG0_EVEN_PARITY 0x1000 12640024Sgibbs#define ADW_SCSI_CFG0_WD_LONG 0x0800 /* 12740024Sgibbs * Watchdog Interval, 12840024Sgibbs * 1: 57 min, 0: 13 sec 12940024Sgibbs */ 13040024Sgibbs#define ADW_SCSI_CFG0_QUEUE_128 0x0400 /* 13140024Sgibbs * Queue Size, 13240024Sgibbs * 1: 128 byte, 13340024Sgibbs * 0: 64 byte 13440024Sgibbs */ 13540024Sgibbs#define ADW_SCSI_CFG0_PRIM_MODE 0x0100 13640024Sgibbs#define ADW_SCSI_CFG0_SCAM_EN 0x0080 13740024Sgibbs#define ADW_SCSI_CFG0_SEL_TMO_LONG 0x0040 /* 13840024Sgibbs * Sel/Resel Timeout, 13940024Sgibbs * 1: 400 ms, 14040024Sgibbs * 0: 1.6 ms 14140024Sgibbs */ 14240024Sgibbs#define ADW_SCSI_CFG0_CFRM_ID 0x0020 /* SCAM id sel. */ 14340024Sgibbs#define ADW_SCSI_CFG0_OUR_ID_EN 0x0010 14440024Sgibbs#define ADW_SCSI_CFG0_OUR_ID 0x000F 14540024Sgibbs 14640024Sgibbs 14740024Sgibbs#define ADW_SCSI_CFG1 0x000E 14840024Sgibbs#define ADW_SCSI_CFG1_BIG_ENDIAN 0x8000 14940024Sgibbs#define ADW_SCSI_CFG1_TERM_POL 0x2000 15040024Sgibbs#define ADW_SCSI_CFG1_SLEW_RATE 0x1000 15140024Sgibbs#define ADW_SCSI_CFG1_FILTER_MASK 0x0C00 15240024Sgibbs#define ADW_SCSI_CFG1_FLTR_DISABLE 0x0000 15340024Sgibbs#define ADW_SCSI_CFG1_FLTR_11_TO_20NS 0x0800 15440024Sgibbs#define ADW_SCSI_CFG1_FLTR_21_TO_39NS 0x0C00 15540024Sgibbs#define ADW_SCSI_CFG1_DIS_ACTIVE_NEG 0x0200 15640024Sgibbs#define ADW_SCSI_CFG1_DIFF_MODE 0x0100 15740024Sgibbs#define ADW_SCSI_CFG1_DIFF_SENSE 0x0080 15840024Sgibbs#define ADW_SCSI_CFG1_TERM_CTL_MANUAL 0x0040 /* Global Term Switch */ 15940024Sgibbs#define ADW_SCSI_CFG1_TERM_CTL_MASK 0x0030 16040024Sgibbs#define ADW_SCSI_CFG1_TERM_CTL_H 0x0020 /* Enable SCSI-H */ 16140024Sgibbs#define ADW_SCSI_CFG1_TERM_CTL_L 0x0010 /* Enable SCSI-L */ 16240024Sgibbs#define ADW_SCSI_CFG1_CABLE_DETECT 0x000F 16340024Sgibbs#define ADW_SCSI_CFG1_EXT16_MASK 0x0008 /* Ext16 cable pres */ 16440024Sgibbs#define ADW_SCSI_CFG1_EXT8_MASK 0x0004 /* Ext8 cable pres */ 16540024Sgibbs#define ADW_SCSI_CFG1_INT8_MASK 0x0002 /* Int8 cable pres */ 16640024Sgibbs#define ADW_SCSI_CFG1_INT16_MASK 0x0001 /* Int16 cable pres */ 16740024Sgibbs#define ADW_SCSI_CFG1_ILLEGAL_CABLE_CONF_A_MASK \ 16840024Sgibbs(ADW_SCSI_CFG1_EXT16_MASK|ADW_SCSI_CFG1_INT8_MASK|ADW_SCSI_CFG1_INT16_MASK) 16940024Sgibbs#define ADW_SCSI_CFG1_ILLEGAL_CABLE_CONF_B_MASK \ 17040024Sgibbs(ADW_SCSI_CFG1_EXT8_MASK|ADW_SCSI_CFG1_INT8_MASK|ADW_SCSI_CFG1_INT16_MASK) 17140024Sgibbs 17256979Sgibbs/* 17356979Sgibbs * Addendum for ASC-38C0800 Chip 17456979Sgibbs */ 17556979Sgibbs#define ADW2_SCSI_CFG1_DIS_TERM_DRV 0x4000 /* 17656979Sgibbs * The Terminators 17756979Sgibbs * must be disabled 17856979Sgibbs * in order to detect 17956979Sgibbs * cable presence 18056979Sgibbs */ 18156979Sgibbs 18256979Sgibbs#define ADW2_SCSI_CFG1_DEV_DETECT 0x1C00 18356979Sgibbs#define ADW2_SCSI_CFG1_DEV_DETECT_HVD 0x1000 18456979Sgibbs#define ADW2_SCSI_CFG1_DEV_DETECT_LVD 0x0800 18556979Sgibbs#define ADW2_SCSI_CFG1_DEV_DETECT_SE 0x0400 18656979Sgibbs 18756979Sgibbs#define ADW2_SCSI_CFG1_TERM_CTL_LVD 0x00C0 /* Ultra2 Only */ 18856979Sgibbs#define ADW2_SCSI_CFG1_TERM_LVD_HI 0x0080 18956979Sgibbs#define ADW2_SCSI_CFG1_TERM_LVD_LO 0x0040 19056979Sgibbs#define ADW2_SCSI_CFG1_EXTLVD_MASK 0x0008 /* ExtLVD cable pres */ 19156979Sgibbs#define ADW2_SCSI_CFG1_INTLVD_MASK 0x0004 /* IntLVD cable pres */ 19256979Sgibbs 19340024Sgibbs#define ADW_MEM_CFG 0x0010 19440024Sgibbs#define ADW_MEM_CFG_BIOS_EN 0x40 19540024Sgibbs#define ADW_MEM_CFG_FAST_EE_CLK 0x20 /* Diagnostic Bit */ 19640024Sgibbs#define ADW_MEM_CFG_RAM_SZ_MASK 0x1C /* RISC RAM Size */ 19740024Sgibbs#define ADW_MEM_CFG_RAM_SZ_2KB 0x00 19840024Sgibbs#define ADW_MEM_CFG_RAM_SZ_4KB 0x04 19940024Sgibbs#define ADW_MEM_CFG_RAM_SZ_8KB 0x08 20040024Sgibbs#define ADW_MEM_CFG_RAM_SZ_16KB 0x0C 20140024Sgibbs#define ADW_MEM_CFG_RAM_SZ_32KB 0x10 20240024Sgibbs#define ADW_MEM_CFG_RAM_SZ_64KB 0x14 20340024Sgibbs 20456979Sgibbs#define ADW_GPIO_CNTL 0x0011 20556979Sgibbs#define ADW_GPIO_DATA 0x0012 20656979Sgibbs 20756979Sgibbs#define ADW_COMMA 0x0014 20856979Sgibbs#define ADW_COMMB 0x0018 20956979Sgibbs 21040024Sgibbs#define ADW_EEP_CMD 0x001A 21140024Sgibbs#define ADW_EEP_CMD_READ 0x0080 /* or in address */ 21240024Sgibbs#define ADW_EEP_CMD_WRITE 0x0040 /* or in address */ 21340024Sgibbs#define ADW_EEP_CMD_WRITE_ABLE 0x0030 21440024Sgibbs#define ADW_EEP_CMD_WRITE_DISABLE 0x0000 21540024Sgibbs#define ADW_EEP_CMD_DONE 0x0200 21640024Sgibbs#define ADW_EEP_CMD_DONE_ERR 0x0001 21740024Sgibbs#define ADW_EEP_DELAY_MS 100 21840024Sgibbs 21940024Sgibbs#define ADW_EEP_DATA 0x001C 22040024Sgibbs 22140024Sgibbs#define ADW_DMA_CFG0 0x0020 22240024Sgibbs#define ADW_DMA_CFG0_BC_THRESH_ENB 0x80 22340024Sgibbs#define ADW_DMA_CFG0_FIFO_THRESH 0x70 22440024Sgibbs#define ADW_DMA_CFG0_FIFO_THRESH_16B 0x00 22540024Sgibbs#define ADW_DMA_CFG0_FIFO_THRESH_32B 0x20 22656979Sgibbs#define ADW_DMA_CFG0_FIFO_THRESH_48B 0x30 22756979Sgibbs#define ADW_DMA_CFG0_FIFO_THRESH_64B 0x40 22856979Sgibbs#define ADW_DMA_CFG0_FIFO_THRESH_80B 0x50 22956979Sgibbs#define ADW_DMA_CFG0_FIFO_THRESH_96B 0x60 23056979Sgibbs#define ADW_DMA_CFG0_FIFO_THRESH_112B 0x70 23140024Sgibbs#define ADW_DMA_CFG0_START_CTL_MASK 0x0C 23240024Sgibbs#define ADW_DMA_CFG0_START_CTL_TH 0x00 /* Start on thresh */ 23340024Sgibbs#define ADW_DMA_CFG0_START_CTL_IDLE 0x04 /* Start when idle */ 23440024Sgibbs#define ADW_DMA_CFG0_START_CTL_TH_IDLE 0x08 /* Either */ 23540024Sgibbs#define ADW_DMA_CFG0_START_CTL_EM_FU 0x0C /* Start on full/empty */ 23640024Sgibbs#define ADW_DMA_CFG0_READ_CMD_MASK 0x03 23740024Sgibbs#define ADW_DMA_CFG0_READ_CMD_MR 0x00 23840024Sgibbs#define ADW_DMA_CFG0_READ_CMD_MRL 0x02 23940024Sgibbs#define ADW_DMA_CFG0_READ_CMD_MRM 0x03 24040024Sgibbs 24156979Sgibbs#define ADW_TICKLE 0x0022 24256979Sgibbs#define ADW_TICKLE_NOP 0x00 24356979Sgibbs#define ADW_TICKLE_A 0x01 24456979Sgibbs#define ADW_TICKLE_B 0x02 24556979Sgibbs#define ADW_TICKLE_C 0x03 24656979Sgibbs 24740024Sgibbs/* Program Counter */ 24840024Sgibbs#define ADW_PC 0x2A 24940024Sgibbs 25040024Sgibbs#define ADW_SCSI_CTRL 0x0034 25140024Sgibbs#define ADW_SCSI_CTRL_RSTOUT 0x2000 25240024Sgibbs 25356979Sgibbs/* 25456979Sgibbs * ASC-38C0800 RAM BIST Register bit definitions 25556979Sgibbs */ 25656979Sgibbs#define ADW_RAM_BIST 0x0038 25756979Sgibbs#define ADW_RAM_BIST_RAM_TEST_MODE 0x80 25856979Sgibbs#define ADW_RAM_BIST_PRE_TEST_MODE 0x40 25956979Sgibbs#define ADW_RAM_BIST_NORMAL_MODE 0x00 26056979Sgibbs#define ADW_RAM_BIST_RAM_TEST_DONE 0x10 26156979Sgibbs#define ADW_RAM_BIST_RAM_TEST_STATUS 0x0F 26256979Sgibbs#define ADW_RAM_BIST_RAM_TEST_HOST_ERR 0x08 26356979Sgibbs#define ADW_RAM_BIST_RAM_TEST_RAM_ERR 0x04 26456979Sgibbs#define ADW_RAM_BIST_RAM_TEST_RISC_ERR 0x02 26556979Sgibbs#define ADW_RAM_BIST_RAM_TEST_SCSI_ERR 0x01 26656979Sgibbs#define ADW_RAM_BIST_RAM_TEST_SUCCESS 0x00 26756979Sgibbs#define ADW_RAM_BIST_PRE_TEST_VALUE 0x05 26856979Sgibbs#define ADW_RAM_BIST_NORMAL_VALUE 0x00 26956979Sgibbs#define ADW_PLL_TEST 0x0039 27056979Sgibbs 27140024Sgibbs#define ADW_SCSI_RESET_HOLD_TIME_US 60 27240024Sgibbs 27340024Sgibbs/* LRAM Constants */ 27456979Sgibbs#define ADW_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */ 27556979Sgibbs#define ADW_3550_IOLEN 0x40 /* I/O Port Range in bytes */ 27640024Sgibbs 27756979Sgibbs#define ADW_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */ 27856979Sgibbs#define ADW_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */ 27956979Sgibbs 28056979Sgibbs#define ADW_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */ 28156979Sgibbs#define ADW_38C1600_IOLEN 0x100 /* I/O Port Range in bytes */ 28256979Sgibbs#define ADW_38C1600_MEMLEN 0x1000 /* Memory Range 4KB */ 28356979Sgibbs 28456979Sgibbs#define ADW_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */ 28556979Sgibbs#define ADW_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */ 28656979Sgibbs 28756979Sgibbs#define PCI_ID_ADVANSYS_3550 0x230010CD00000000ull 28856979Sgibbs#define PCI_ID_ADVANSYS_38C0800_REV1 0x250010CD00000000ull 28956979Sgibbs#define PCI_ID_ADVANSYS_38C1600_REV1 0x270010CD00000000ull 29056979Sgibbs#define PCI_ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull 29156979Sgibbs#define PCI_ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull 29256979Sgibbs 29340024Sgibbs/* ====================== SCSI Request Structures =========================== */ 29440024Sgibbs 29540024Sgibbs#define ADW_NO_OF_SG_PER_BLOCK 15 29640024Sgibbs 29740024Sgibbs/* 29840024Sgibbs * Although the adapter can deal with S/G lists of indefinite size, 29940024Sgibbs * we limit the list to 30 to conserve space as the kernel can only send 30040024Sgibbs * us buffers of at most 64KB currently. 30140024Sgibbs */ 30240024Sgibbs#define ADW_SG_BLOCKCNT 2 30340024Sgibbs#define ADW_SGSIZE (ADW_NO_OF_SG_PER_BLOCK * ADW_SG_BLOCKCNT) 30440024Sgibbs 30540024Sgibbsstruct adw_sg_elm { 30640024Sgibbs u_int32_t sg_addr; 30740024Sgibbs u_int32_t sg_count; 30840024Sgibbs}; 30940024Sgibbs 31040024Sgibbs/* sg block structure used by the microcode */ 31140024Sgibbsstruct adw_sg_block { 31240024Sgibbs u_int8_t reserved1; 31340024Sgibbs u_int8_t reserved2; 31456979Sgibbs u_int8_t reserved3; 31556979Sgibbs u_int8_t sg_cnt; /* Valid entries in this block */ 31640024Sgibbs u_int32_t sg_busaddr_next; /* link to the next sg block */ 31740024Sgibbs struct adw_sg_elm sg_list[ADW_NO_OF_SG_PER_BLOCK]; 31840024Sgibbs}; 31940024Sgibbs 32040024Sgibbs/* Structure representing a single allocation block of adw sg blocks */ 32140024Sgibbsstruct sg_map_node { 32240024Sgibbs bus_dmamap_t sg_dmamap; 32340024Sgibbs bus_addr_t sg_physaddr; 32440024Sgibbs struct adw_sg_block* sg_vaddr; 32560938Sjake SLIST_ENTRY(sg_map_node) links; 32640024Sgibbs}; 32740024Sgibbs 32840024Sgibbstypedef enum { 32940024Sgibbs QHSTA_NO_ERROR = 0x00, 33040024Sgibbs QHSTA_M_SEL_TIMEOUT = 0x11, 33140024Sgibbs QHSTA_M_DATA_OVER_RUN = 0x12, 33240024Sgibbs QHSTA_M_UNEXPECTED_BUS_FREE = 0x13, 33340024Sgibbs QHSTA_M_QUEUE_ABORTED = 0x15, 33440024Sgibbs QHSTA_M_SXFR_SDMA_ERR = 0x16, /* SCSI DMA Error */ 33540024Sgibbs QHSTA_M_SXFR_SXFR_PERR = 0x17, /* SCSI Bus Parity Error */ 33640024Sgibbs QHSTA_M_RDMA_PERR = 0x18, /* RISC PCI DMA parity error */ 33740024Sgibbs QHSTA_M_SXFR_OFF_UFLW = 0x19, /* Offset Underflow */ 33840024Sgibbs QHSTA_M_SXFR_OFF_OFLW = 0x20, /* Offset Overflow */ 33940024Sgibbs QHSTA_M_SXFR_WD_TMO = 0x21, /* Watchdog Timeout */ 34040024Sgibbs QHSTA_M_SXFR_DESELECTED = 0x22, /* Deselected */ 34140024Sgibbs QHSTA_M_SXFR_XFR_PH_ERR = 0x24, /* Transfer Phase Error */ 34240024Sgibbs QHSTA_M_SXFR_UNKNOWN_ERROR = 0x25, /* SXFR_STATUS Unknown Error */ 34357679Sgibbs QHSTA_M_SCSI_BUS_RESET = 0x30, /* Request aborted from SBR */ 34457679Sgibbs QHSTA_M_SCSI_BUS_RESET_UNSOL= 0x31, /* Request aborted from unsol. SBR*/ 34557679Sgibbs QHSTA_M_BUS_DEVICE_RESET = 0x32, /* Request aborted from BDR */ 34657679Sgibbs QHSTA_M_DIRECTION_ERR = 0x35, /* Data Phase mismatch */ 34757679Sgibbs QHSTA_M_DIRECTION_ERR_HUNG = 0x36, /* Data Phase mismatch - bus hang */ 34840024Sgibbs QHSTA_M_WTM_TIMEOUT = 0x41, 34940024Sgibbs QHSTA_M_BAD_CMPL_STATUS_IN = 0x42, 35040024Sgibbs QHSTA_M_NO_AUTO_REQ_SENSE = 0x43, 35140024Sgibbs QHSTA_M_AUTO_REQ_SENSE_FAIL = 0x44, 35257679Sgibbs QHSTA_M_INVALID_DEVICE = 0x45, /* Bad target ID */ 35357679Sgibbs QHSTA_M_FROZEN_TIDQ = 0x46, /* TID Queue frozen. */ 35457679Sgibbs QHSTA_M_SGBACKUP_ERROR = 0x47 /* Scatter-Gather backup error */ 35540024Sgibbs} host_status_t; 35640024Sgibbs 35740024Sgibbstypedef enum { 35840024Sgibbs QD_NO_STATUS = 0x00, /* Request not completed yet. */ 35940024Sgibbs QD_NO_ERROR = 0x01, 36040024Sgibbs QD_ABORTED_BY_HOST = 0x02, 36140024Sgibbs QD_WITH_ERROR = 0x04 36240024Sgibbs} done_status_t; 36340024Sgibbs 36440024Sgibbs/* 36540024Sgibbs * Microcode request structure 36640024Sgibbs * 36740024Sgibbs * All fields in this structure are used by the microcode so their 36840024Sgibbs * size and ordering cannot be changed. 36940024Sgibbs */ 37040024Sgibbsstruct adw_scsi_req_q { 37140024Sgibbs u_int8_t cntl; /* Ucode flags and state. */ 37256979Sgibbs u_int8_t target_cmd; 37340024Sgibbs u_int8_t target_id; /* Device target identifier. */ 37440024Sgibbs u_int8_t target_lun; /* Device target logical unit number. */ 37540024Sgibbs u_int32_t data_addr; /* Data buffer physical address. */ 37640024Sgibbs u_int32_t data_cnt; /* Data count. Ucode sets to residual. */ 37756979Sgibbs u_int32_t sense_baddr; /* Sense buffer bus address. */ 37856979Sgibbs u_int32_t carrier_baddr; /* Carrier bus address. */ 37956979Sgibbs u_int8_t mflag; /* microcode flag field. */ 38040024Sgibbs u_int8_t sense_len; /* Auto-sense length. Residual on complete. */ 38140024Sgibbs u_int8_t cdb_len; /* SCSI CDB length. */ 38256979Sgibbs u_int8_t scsi_cntl; /* SCSI command control flags (tags, nego) */ 38356979Sgibbs#define ADW_QSC_NO_DISC 0x01 38456979Sgibbs#define ADW_QSC_NO_TAGMSG 0x02 38556979Sgibbs#define ADW_QSC_NO_SYNC 0x04 38656979Sgibbs#define ADW_QSC_NO_WIDE 0x08 38756979Sgibbs#define ADW_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR */ 38857679Sgibbs#define ADW_QSC_SIMPLE_Q_TAG 0x00 38956979Sgibbs#define ADW_QSC_HEAD_OF_Q_TAG 0x40 39056979Sgibbs#define ADW_QSC_ORDERED_Q_TAG 0x80 39140024Sgibbs u_int8_t done_status; /* Completion status. */ 39240024Sgibbs u_int8_t scsi_status; /* SCSI status byte. */ 39340024Sgibbs u_int8_t host_status; /* Ucode host status. */ 39456979Sgibbs u_int8_t sg_wk_ix; /* Microcode working SG index. */ 39540024Sgibbs u_int8_t cdb[12]; /* SCSI command block. */ 39640024Sgibbs u_int32_t sg_real_addr; /* SG list physical address. */ 39756979Sgibbs u_int32_t scsi_req_baddr; /* Bus address of this structure. */ 39856979Sgibbs u_int32_t sg_wk_data_cnt; /* Saved data count at disconnection. */ 39956979Sgibbs /* 40056979Sgibbs * The 'tokens' placed in these two fields are 40156979Sgibbs * used to identify the scsi request and the next 40256979Sgibbs * carrier in the response queue, *not* physical 40356979Sgibbs * addresses. This driver uses byte offsets for 40456979Sgibbs * portability and speed of mapping back to either 40556979Sgibbs * a virtual or physical address. 40656979Sgibbs */ 40756979Sgibbs u_int32_t scsi_req_bo; /* byte offset of this structure */ 40856979Sgibbs u_int32_t carrier_bo; /* byte offst of our carrier. */ 40940024Sgibbs}; 41040024Sgibbs 41140024Sgibbstypedef enum { 41240024Sgibbs ACB_FREE = 0x00, 41340024Sgibbs ACB_ACTIVE = 0x01, 41457679Sgibbs ACB_RELEASE_SIMQ = 0x02, 41557679Sgibbs ACB_RECOVERY_ACB = 0x04 41640024Sgibbs} acb_state; 41740024Sgibbs 41840024Sgibbsstruct acb { 41940024Sgibbs struct adw_scsi_req_q queue; 42040024Sgibbs bus_dmamap_t dmamap; 42140024Sgibbs acb_state state; 42240024Sgibbs union ccb *ccb; 42340024Sgibbs struct adw_sg_block* sg_blocks; 424241588Sjhb struct callout timer; 42540024Sgibbs bus_addr_t sg_busaddr; 42640024Sgibbs struct scsi_sense_data sense_data; 42760938Sjake SLIST_ENTRY(acb) links; 42840024Sgibbs}; 42940024Sgibbs 43040024Sgibbs/* 43140024Sgibbs * EEPROM configuration format 43240024Sgibbs * 43340024Sgibbs * Field naming convention: 43440024Sgibbs * 43540024Sgibbs * *_enable indicates the field enables or disables the feature. The 43640024Sgibbs * value is never reset. 43740024Sgibbs * 43840024Sgibbs * *_able indicates both whether a feature should be enabled or disabled 43940024Sgibbs * and whether a device is capable of the feature. At initialization 44040024Sgibbs * this field may be set, but later if a device is found to be incapable 44140024Sgibbs * of the feature, the field is cleared. 44240024Sgibbs * 44340024Sgibbs * Default values are maintained in a_init.c in the structure 44440024Sgibbs * Default_EEPROM_Config. 44540024Sgibbs */ 44640024Sgibbsstruct adw_eeprom 44740024Sgibbs{ 44840024Sgibbs u_int16_t cfg_lsw; /* 00 power up initialization */ 44940024Sgibbs#define ADW_EEPROM_BIG_ENDIAN 0x8000 45040024Sgibbs#define ADW_EEPROM_BIOS_ENABLE 0x4000 45140024Sgibbs#define ADW_EEPROM_TERM_POL 0x2000 45256979Sgibbs#define ADW_EEPROM_CIS_LD 0x1000 45340024Sgibbs 45440024Sgibbs /* bit 13 set - Term Polarity Control */ 45540024Sgibbs /* bit 14 set - BIOS Enable */ 45640024Sgibbs /* bit 15 set - Big Endian Mode */ 45740024Sgibbs u_int16_t cfg_msw; /* unused */ 45840024Sgibbs u_int16_t disc_enable; 45940024Sgibbs u_int16_t wdtr_able; 46056979Sgibbs union { 46156979Sgibbs /* 46256979Sgibbs * sync enable bits for UW cards, 46356979Sgibbs * actual sync rate for TID 0-3 46456979Sgibbs * on U2W and U160 cards. 46556979Sgibbs */ 46656979Sgibbs u_int16_t sync_enable; 46756979Sgibbs u_int16_t sdtr1; 46856979Sgibbs } sync1; 46940024Sgibbs u_int16_t start_motor; 47040024Sgibbs u_int16_t tagqng_able; 47140024Sgibbs u_int16_t bios_scan; 47240024Sgibbs u_int16_t scam_tolerant; 47340024Sgibbs 47440024Sgibbs u_int8_t adapter_scsi_id; 47540024Sgibbs u_int8_t bios_boot_delay; 47640024Sgibbs 47740024Sgibbs u_int8_t scsi_reset_delay; 47840024Sgibbs u_int8_t bios_id_lun; /* high nibble is lun */ 47940024Sgibbs /* low nibble is scsi id */ 48040024Sgibbs 48156979Sgibbs u_int8_t termination_se; /* 0 - automatic */ 48240024Sgibbs#define ADW_EEPROM_TERM_AUTO 0 48340024Sgibbs#define ADW_EEPROM_TERM_OFF 1 48440024Sgibbs#define ADW_EEPROM_TERM_HIGH_ON 2 48540024Sgibbs#define ADW_EEPROM_TERM_BOTH_ON 3 48640024Sgibbs 48756979Sgibbs u_int8_t termination_lvd; 48856979Sgibbs u_int16_t bios_ctrl; 48956979Sgibbs#define ADW_BIOS_INIT_DIS 0x0001 /* Don't act as initiator */ 49056979Sgibbs#define ADW_BIOS_EXT_TRANS 0x0002 /* > 1 GB support */ 49156979Sgibbs#define ADW_BIOS_MORE_2DISK 0x0004 /* > 1 GB support */ 49256979Sgibbs#define ADW_BIOS_NO_REMOVABLE 0x0008 /* don't support removable media */ 49356979Sgibbs#define ADW_BIOS_CD_BOOT 0x0010 /* support bootable CD */ 49456979Sgibbs#define ADW_BIOS_SCAN_EN 0x0020 /* BIOS SCAN enabled */ 49556979Sgibbs#define ADW_BIOS_MULTI_LUN 0x0040 /* probe luns */ 49656979Sgibbs#define ADW_BIOS_MESSAGE 0x0080 /* display BIOS message */ 49756979Sgibbs#define ADW_BIOS_RESET_BUS 0x0200 /* reset SCSI bus durint init */ 49856979Sgibbs#define ADW_BIOS_QUIET 0x0800 /* No verbose initialization */ 49956979Sgibbs#define ADW_BIOS_SCSI_PAR_EN 0x1000 /* SCSI parity enabled */ 50040024Sgibbs 50156979Sgibbs union { 50256979Sgibbs /* 13 50356979Sgibbs * ultra enable bits for UW cards, 50456979Sgibbs * actual sync rate for TID 4-7 50556979Sgibbs * on U2W and U160 cards. 50656979Sgibbs */ 50756979Sgibbs u_int16_t ultra_enable; 50856979Sgibbs u_int16_t sdtr2; 50956979Sgibbs } sync2; 51056979Sgibbs union { 51156979Sgibbs /* 14 51256979Sgibbs * reserved for UW cards, 51356979Sgibbs * actual sync rate for TID 8-11 51456979Sgibbs * on U2W and U160 cards. 51556979Sgibbs */ 51656979Sgibbs u_int16_t reserved; 51756979Sgibbs u_int16_t sdtr3; 51856979Sgibbs } sync3; 51940024Sgibbs u_int8_t max_host_qng; /* 15 maximum host queuing */ 52040024Sgibbs u_int8_t max_dvc_qng; /* maximum per device queuing */ 52140024Sgibbs u_int16_t dvc_cntl; /* 16 control bit for driver */ 52256979Sgibbs union { 52356979Sgibbs /* 17 52456979Sgibbs * reserved for UW cards, 52556979Sgibbs * actual sync rate for TID 12-15 52656979Sgibbs * on U2W and U160 cards. 52756979Sgibbs */ 52856979Sgibbs u_int16_t reserved; 52956979Sgibbs u_int16_t sdtr4; 53056979Sgibbs } sync4; 53156979Sgibbs u_int16_t serial_number[3]; /* 18-20 */ 53256979Sgibbs u_int16_t checksum; /* 21 */ 53356979Sgibbs u_int8_t oem_name[16]; /* 22 - 29 */ 53456979Sgibbs u_int16_t dvc_err_code; /* 30 */ 53556979Sgibbs u_int16_t adv_err_code; /* 31 */ 53656979Sgibbs u_int16_t adv_err_addr; /* 32 */ 53756979Sgibbs u_int16_t saved_dvc_err_code; /* 33 */ 53856979Sgibbs u_int16_t saved_adv_err_code; /* 34 */ 53956979Sgibbs u_int16_t saved_adv_err_addr; /* 35 */ 54056979Sgibbs u_int16_t reserved[20]; /* 36 - 55 */ 54156979Sgibbs u_int16_t cisptr_lsw; /* 56 CIS data */ 54256979Sgibbs u_int16_t cisptr_msw; /* 57 CIS data */ 54356979Sgibbs u_int32_t subid; /* 58-59 SubSystem Vendor/Dev ID */ 54456979Sgibbs u_int16_t reserved2[4]; 54540024Sgibbs}; 54640024Sgibbs 54740024Sgibbs/* EEProm Addresses */ 54840024Sgibbs#define ADW_EEP_DVC_CFG_BEGIN 0x00 54940024Sgibbs#define ADW_EEP_DVC_CFG_END (offsetof(struct adw_eeprom, checksum)/2) 55040024Sgibbs#define ADW_EEP_DVC_CTL_BEGIN (offsetof(struct adw_eeprom, oem_name)/2) 55140024Sgibbs#define ADW_EEP_MAX_WORD_ADDR (sizeof(struct adw_eeprom)/2) 55240024Sgibbs 55357679Sgibbs#define ADW_BUS_RESET_HOLD_DELAY_US 100 55457679Sgibbs 55540024Sgibbstypedef enum { 55656979Sgibbs ADW_CHIP_NONE, 55756979Sgibbs ADW_CHIP_ASC3550, /* Ultra-Wide IC */ 55856979Sgibbs ADW_CHIP_ASC38C0800, /* Ultra2-Wide/LVD IC */ 55956979Sgibbs ADW_CHIP_ASC38C1600 /* Ultra3-Wide/LVD2 IC */ 56056979Sgibbs} adw_chip; 56156979Sgibbs 56256979Sgibbstypedef enum { 56356979Sgibbs ADW_FENONE = 0x0000, 56456979Sgibbs ADW_ULTRA = 0x0001, /* Supports 20MHz Transfers */ 56556979Sgibbs ADW_ULTRA2 = 0x0002, /* Supports 40MHz Transfers */ 56656979Sgibbs ADW_DT = 0x0004, /* Supports Double Transistion REQ/ACK*/ 56756979Sgibbs ADW_WIDE = 0x0008, /* Wide Channel */ 56856979Sgibbs ADW_ASC3550_FE = ADW_ULTRA, 56956979Sgibbs ADW_ASC38C0800_FE = ADW_ULTRA2, 57056979Sgibbs ADW_ASC38C1600_FE = ADW_ULTRA2|ADW_DT 57156979Sgibbs} adw_feature; 57256979Sgibbs 57356979Sgibbstypedef enum { 57456979Sgibbs ADW_FNONE = 0x0000, 57556979Sgibbs ADW_EEPROM_FAILED = 0x0001 57656979Sgibbs} adw_flag; 57756979Sgibbs 57856979Sgibbstypedef enum { 57940024Sgibbs ADW_STATE_NORMAL = 0x00, 58040024Sgibbs ADW_RESOURCE_SHORTAGE = 0x01 58140024Sgibbs} adw_state; 58240024Sgibbs 58356979Sgibbstypedef enum { 58456979Sgibbs ADW_MC_SDTR_ASYNC, 58556979Sgibbs ADW_MC_SDTR_5, 58656979Sgibbs ADW_MC_SDTR_10, 58756979Sgibbs ADW_MC_SDTR_20, 58856979Sgibbs ADW_MC_SDTR_40, 58956979Sgibbs ADW_MC_SDTR_80 59056979Sgibbs} adw_mc_sdtr; 59156979Sgibbs 59256979Sgibbsstruct adw_syncrate 59356979Sgibbs{ 59456979Sgibbs adw_mc_sdtr mc_sdtr; 59556979Sgibbs u_int8_t period; 59656979Sgibbs char *rate; 59756979Sgibbs}; 59856979Sgibbs 59956979Sgibbs/* We have an input and output queue for our carrier structures */ 60056979Sgibbs#define ADW_OUTPUT_QUEUE 0 /* Offset into carriers member */ 60156979Sgibbs#define ADW_INPUT_QUEUE 1 /* Offset into carriers member */ 60256979Sgibbs#define ADW_NUM_CARRIER_QUEUES 2 60340024Sgibbsstruct adw_softc 60440024Sgibbs{ 605241588Sjhb struct resource *res; 60640024Sgibbs adw_state state; 60740024Sgibbs bus_dma_tag_t buffer_dmat; 60840024Sgibbs struct acb *acbs; 60956979Sgibbs struct adw_carrier *carriers; 61056979Sgibbs struct adw_carrier *free_carriers; 61156979Sgibbs struct adw_carrier *commandq; 61256979Sgibbs struct adw_carrier *responseq; 61360938Sjake LIST_HEAD(, ccb_hdr) pending_ccbs; 61460938Sjake SLIST_HEAD(, acb) free_acb_list; 61540024Sgibbs bus_dma_tag_t parent_dmat; 61656979Sgibbs bus_dma_tag_t carrier_dmat; /* dmat for our acb carriers*/ 61756979Sgibbs bus_dmamap_t carrier_dmamap; 61840024Sgibbs bus_dma_tag_t acb_dmat; /* dmat for our ccb array */ 61940024Sgibbs bus_dmamap_t acb_dmamap; 62040024Sgibbs bus_dma_tag_t sg_dmat; /* dmat for our sg maps */ 62160938Sjake SLIST_HEAD(, sg_map_node) sg_maps; 62240024Sgibbs bus_addr_t acb_busbase; 62356979Sgibbs bus_addr_t carrier_busbase; 62456979Sgibbs adw_chip chip; 62556979Sgibbs adw_feature features; 62656979Sgibbs adw_flag flags; 62756979Sgibbs u_int memsize; 62856979Sgibbs char channel; 629241588Sjhb struct mtx lock; 63040024Sgibbs struct cam_path *path; 63140024Sgibbs struct cam_sim *sim; 63256979Sgibbs struct resource *regs; 63356979Sgibbs struct resource *irq; 63456979Sgibbs void *ih; 63556979Sgibbs const struct adw_mcode *mcode_data; 63656979Sgibbs const struct adw_eeprom *default_eeprom; 63756979Sgibbs device_t device; 63856979Sgibbs int regs_res_type; 63956979Sgibbs int regs_res_id; 64056979Sgibbs int irq_res_type; 64140024Sgibbs u_int max_acbs; 64240024Sgibbs u_int num_acbs; 64340024Sgibbs u_int initiator_id; 64440024Sgibbs u_int init_level; 64540024Sgibbs cam_status last_reset; /* Last reset type */ 64656979Sgibbs u_int16_t bios_ctrl; 64740024Sgibbs u_int16_t user_wdtr; 64856979Sgibbs u_int16_t user_sdtr[4]; /* A nibble per-device */ 64940024Sgibbs u_int16_t user_tagenb; 65040024Sgibbs u_int16_t tagenb; 65140024Sgibbs u_int16_t user_discenb; 65240024Sgibbs u_int16_t serial_number[3]; 65340024Sgibbs}; 65440024Sgibbs 65556979Sgibbsextern const struct adw_eeprom adw_asc3550_default_eeprom; 65656979Sgibbsextern const struct adw_eeprom adw_asc38C0800_default_eeprom; 65756979Sgibbsextern const struct adw_syncrate adw_syncrates[]; 65856979Sgibbsextern const int adw_num_syncrates; 65940024Sgibbs 66040024Sgibbs#define adw_inb(adw, port) \ 661241588Sjhb bus_read_1((adw)->res, port) 66240024Sgibbs#define adw_inw(adw, port) \ 663241588Sjhb bus_read_2((adw)->res, port) 66440024Sgibbs#define adw_inl(adw, port) \ 665241588Sjhb bus_read_4((adw)->res, port) 66640024Sgibbs 66740024Sgibbs#define adw_outb(adw, port, value) \ 668241588Sjhb bus_write_1((adw)->res, port, value) 66940024Sgibbs#define adw_outw(adw, port, value) \ 670241588Sjhb bus_write_2((adw)->res, port, value) 67140024Sgibbs#define adw_outl(adw, port, value) \ 672241588Sjhb bus_write_4((adw)->res, port, value) 67340024Sgibbs 67456979Sgibbs#define adw_set_multi_2(adw, port, value, count) \ 675241588Sjhb bus_set_multi_2((adw)->res, port, value, count) 67656979Sgibbs 67740024Sgibbsstatic __inline u_int adw_lram_read_8(struct adw_softc *adw, u_int addr); 67840024Sgibbsstatic __inline u_int adw_lram_read_16(struct adw_softc *adw, u_int addr); 67940024Sgibbsstatic __inline u_int adw_lram_read_32(struct adw_softc *adw, u_int addr); 68040024Sgibbsstatic __inline void adw_lram_write_8(struct adw_softc *adw, u_int addr, 68140024Sgibbs u_int value); 68240024Sgibbsstatic __inline void adw_lram_write_16(struct adw_softc *adw, u_int addr, 68340024Sgibbs u_int value); 68440024Sgibbsstatic __inline void adw_lram_write_32(struct adw_softc *adw, u_int addr, 68540024Sgibbs u_int value); 68640024Sgibbs 68756979Sgibbsstatic __inline u_int32_t acbvtobo(struct adw_softc *adw, 68856979Sgibbs struct acb *acb); 68956979Sgibbsstatic __inline u_int32_t acbvtob(struct adw_softc *adw, 69056979Sgibbs struct acb *acb); 69156979Sgibbsstatic __inline struct acb * acbbotov(struct adw_softc *adw, 69256979Sgibbs u_int32_t busaddr); 69356979Sgibbsstatic __inline struct acb * acbbtov(struct adw_softc *adw, 69456979Sgibbs u_int32_t busaddr); 69556979Sgibbsstatic __inline u_int32_t carriervtobo(struct adw_softc *adw, 69656979Sgibbs struct adw_carrier *carrier); 69756979Sgibbsstatic __inline u_int32_t carriervtob(struct adw_softc *adw, 69856979Sgibbs struct adw_carrier *carrier); 69956979Sgibbsstatic __inline struct adw_carrier * 70056979Sgibbs carrierbotov(struct adw_softc *adw, 70156979Sgibbs u_int32_t byte_offset); 70256979Sgibbsstatic __inline struct adw_carrier * 70356979Sgibbs carrierbtov(struct adw_softc *adw, 70456979Sgibbs u_int32_t baddr); 70556979Sgibbs 70640024Sgibbsstatic __inline u_int 70740024Sgibbsadw_lram_read_8(struct adw_softc *adw, u_int addr) 70840024Sgibbs{ 70940024Sgibbs adw_outw(adw, ADW_RAM_ADDR, addr); 71040024Sgibbs return (adw_inb(adw, ADW_RAM_DATA)); 71140024Sgibbs} 71240024Sgibbs 71340024Sgibbsstatic __inline u_int 71440024Sgibbsadw_lram_read_16(struct adw_softc *adw, u_int addr) 71540024Sgibbs{ 71640024Sgibbs adw_outw(adw, ADW_RAM_ADDR, addr); 71740024Sgibbs return (adw_inw(adw, ADW_RAM_DATA)); 71840024Sgibbs} 71940024Sgibbs 72040024Sgibbsstatic __inline u_int 72140024Sgibbsadw_lram_read_32(struct adw_softc *adw, u_int addr) 72240024Sgibbs{ 72340024Sgibbs u_int retval; 72440024Sgibbs 72540024Sgibbs adw_outw(adw, ADW_RAM_ADDR, addr); 72640024Sgibbs retval = adw_inw(adw, ADW_RAM_DATA); 72740024Sgibbs retval |= (adw_inw(adw, ADW_RAM_DATA) << 16); 72840024Sgibbs return (retval); 72940024Sgibbs} 73040024Sgibbs 73140024Sgibbsstatic __inline void 73240024Sgibbsadw_lram_write_8(struct adw_softc *adw, u_int addr, u_int value) 73340024Sgibbs{ 73440024Sgibbs adw_outw(adw, ADW_RAM_ADDR, addr); 73540024Sgibbs adw_outb(adw, ADW_RAM_DATA, value); 73640024Sgibbs} 73740024Sgibbs 73840024Sgibbsstatic __inline void 73940024Sgibbsadw_lram_write_16(struct adw_softc *adw, u_int addr, u_int value) 74040024Sgibbs{ 74140024Sgibbs adw_outw(adw, ADW_RAM_ADDR, addr); 74240024Sgibbs adw_outw(adw, ADW_RAM_DATA, value); 74340024Sgibbs} 74440024Sgibbs 74540024Sgibbsstatic __inline void 74640024Sgibbsadw_lram_write_32(struct adw_softc *adw, u_int addr, u_int value) 74740024Sgibbs{ 74840024Sgibbs adw_outw(adw, ADW_RAM_ADDR, addr); 74940024Sgibbs adw_outw(adw, ADW_RAM_DATA, value); 75040024Sgibbs adw_outw(adw, ADW_RAM_DATA, value >> 16); 75140024Sgibbs} 75240024Sgibbs 75356979Sgibbsstatic __inline u_int32_t 75456979Sgibbsacbvtobo(struct adw_softc *adw, struct acb *acb) 75556979Sgibbs{ 75656979Sgibbs return ((u_int32_t)((caddr_t)acb - (caddr_t)adw->acbs)); 75756979Sgibbs} 75856979Sgibbs 75956979Sgibbsstatic __inline u_int32_t 76056979Sgibbsacbvtob(struct adw_softc *adw, struct acb *acb) 76156979Sgibbs{ 76256979Sgibbs return (adw->acb_busbase + acbvtobo(adw, acb)); 76356979Sgibbs} 76456979Sgibbs 76556979Sgibbsstatic __inline struct acb * 76656979Sgibbsacbbotov(struct adw_softc *adw, u_int32_t byteoffset) 76756979Sgibbs{ 76856979Sgibbs return ((struct acb *)((caddr_t)adw->acbs + byteoffset)); 76956979Sgibbs} 77056979Sgibbs 77156979Sgibbsstatic __inline struct acb * 77256979Sgibbsacbbtov(struct adw_softc *adw, u_int32_t busaddr) 77356979Sgibbs{ 77456979Sgibbs return (acbbotov(adw, busaddr - adw->acb_busbase)); 77556979Sgibbs} 77656979Sgibbs 77756979Sgibbs/* 77856979Sgibbs * Return the byte offset for a carrier relative to our array of carriers. 77956979Sgibbs */ 78056979Sgibbsstatic __inline u_int32_t 78156979Sgibbscarriervtobo(struct adw_softc *adw, struct adw_carrier *carrier) 78256979Sgibbs{ 78356979Sgibbs return ((u_int32_t)((caddr_t)carrier - (caddr_t)adw->carriers)); 78456979Sgibbs} 78556979Sgibbs 78656979Sgibbsstatic __inline u_int32_t 78756979Sgibbscarriervtob(struct adw_softc *adw, struct adw_carrier *carrier) 78856979Sgibbs{ 78956979Sgibbs return (adw->carrier_busbase + carriervtobo(adw, carrier)); 79056979Sgibbs} 79156979Sgibbs 79256979Sgibbsstatic __inline struct adw_carrier * 79356979Sgibbscarrierbotov(struct adw_softc *adw, u_int32_t byte_offset) 79456979Sgibbs{ 79556979Sgibbs return ((struct adw_carrier *)((caddr_t)adw->carriers + byte_offset)); 79656979Sgibbs} 79756979Sgibbs 79856979Sgibbsstatic __inline struct adw_carrier * 79956979Sgibbscarrierbtov(struct adw_softc *adw, u_int32_t baddr) 80056979Sgibbs{ 80156979Sgibbs return (carrierbotov(adw, baddr - adw->carrier_busbase)); 80256979Sgibbs} 80356979Sgibbs 80440024Sgibbs/* Intialization */ 80556979Sgibbsint adw_find_signature(struct adw_softc *adw); 80640024Sgibbsvoid adw_reset_chip(struct adw_softc *adw); 80757679Sgibbsint adw_reset_bus(struct adw_softc *adw); 80840024Sgibbsu_int16_t adw_eeprom_read(struct adw_softc *adw, struct adw_eeprom *buf); 80940024Sgibbsvoid adw_eeprom_write(struct adw_softc *adw, struct adw_eeprom *buf); 81040024Sgibbsint adw_init_chip(struct adw_softc *adw, u_int term_scsicfg1); 81156979Sgibbsvoid adw_set_user_sdtr(struct adw_softc *adw, 81256979Sgibbs u_int tid, u_int mc_sdtr); 81356979Sgibbsu_int adw_get_user_sdtr(struct adw_softc *adw, u_int tid); 81456979Sgibbsvoid adw_set_chip_sdtr(struct adw_softc *adw, u_int tid, u_int sdtr); 81556979Sgibbsu_int adw_get_chip_sdtr(struct adw_softc *adw, u_int tid); 81656979Sgibbsu_int adw_find_sdtr(struct adw_softc *adw, u_int period); 81756979Sgibbsu_int adw_find_period(struct adw_softc *adw, u_int mc_sdtr); 81856979Sgibbsu_int adw_hshk_cfg_period_factor(u_int tinfo); 81940024Sgibbs 82040024Sgibbs/* Idle Commands */ 82157679Sgibbsadw_idle_cmd_status_t adw_idle_cmd_send(struct adw_softc *adw, u_int cmd, 82240024Sgibbs u_int parameter); 82340024Sgibbs 82440024Sgibbs/* SCSI Transaction Processing */ 82540024Sgibbsstatic __inline void adw_send_acb(struct adw_softc *adw, struct acb *acb, 82640024Sgibbs u_int32_t acb_baddr); 82740024Sgibbs 82856979Sgibbsstatic __inline void adw_tickle_risc(struct adw_softc *adw, u_int value) 82956979Sgibbs{ 83056979Sgibbs /* 83156979Sgibbs * Tickle the RISC to tell it to read its Command Queue Head pointer. 83256979Sgibbs */ 83356979Sgibbs adw_outb(adw, ADW_TICKLE, value); 83456979Sgibbs if (adw->chip == ADW_CHIP_ASC3550) { 83556979Sgibbs /* 83656979Sgibbs * Clear the tickle value. In the ASC-3550 the RISC flag 83756979Sgibbs * command 'clr_tickle_a' does not work unless the host 83856979Sgibbs * value is cleared. 83956979Sgibbs */ 84056979Sgibbs adw_outb(adw, ADW_TICKLE, ADW_TICKLE_NOP); 84156979Sgibbs } 84256979Sgibbs} 84356979Sgibbs 84440024Sgibbsstatic __inline void 84540024Sgibbsadw_send_acb(struct adw_softc *adw, struct acb *acb, u_int32_t acb_baddr) 84640024Sgibbs{ 84756979Sgibbs struct adw_carrier *new_cq; 84840024Sgibbs 84956979Sgibbs new_cq = adw->free_carriers; 85056979Sgibbs adw->free_carriers = carrierbotov(adw, new_cq->next_ba); 85156979Sgibbs new_cq->next_ba = ADW_CQ_STOPPER; 85240024Sgibbs 85356979Sgibbs acb->queue.carrier_baddr = adw->commandq->carr_ba; 85456979Sgibbs acb->queue.carrier_bo = adw->commandq->carr_offset; 85556979Sgibbs adw->commandq->areq_ba = acbvtob(adw, acb); 85656979Sgibbs adw->commandq->next_ba = new_cq->carr_ba; 85756979Sgibbs#if 0 85856979Sgibbs printf("EnQ 0x%x 0x%x 0x%x 0x%x\n", 85956979Sgibbs adw->commandq->carr_offset, 86056979Sgibbs adw->commandq->carr_ba, 86156979Sgibbs adw->commandq->areq_ba, 86256979Sgibbs adw->commandq->next_ba); 86356979Sgibbs#endif 86456979Sgibbs adw->commandq = new_cq; 86540024Sgibbs 86656979Sgibbs 86756979Sgibbs adw_tickle_risc(adw, ADW_TICKLE_A); 86840024Sgibbs} 86940024Sgibbs 87040024Sgibbs#endif /* _ADWLIB_H_ */ 871