Advanced Systems Inc. SCSI Controller driver and ISA/VL front end.
I have only tested the ABP5140 card and only with a single CDROM drive but it seems to work fine. This driver relies on features found only in the SCSI branch so will not work in -current until those changes are brought in. It also doesn't have any error handling code *yet*. The goal is to use this driver as the development platform for the new generic SCSI layer error recovery/handling code. PCI and EISA front ends will show up as soon as I get my hands on the cards. There are also a few issues in the driver that I need to clear up with AdvanSys before I can suggest sticking one of these cards in your server. 8-) Thanks to AdvanSys for releasing this code under a suitable copyright. Obtained from: Ported from the Linux driver writen by bobf@advansys.com (Bob Frey).
This commit is contained in:
commit
2032d50b04
1654
sys/dev/advansys/advlib.c
Normal file
1654
sys/dev/advansys/advlib.c
Normal file
File diff suppressed because it is too large
Load Diff
741
sys/dev/advansys/advlib.h
Normal file
741
sys/dev/advansys/advlib.h
Normal file
@ -0,0 +1,741 @@
|
||||
/*
|
||||
* Definitions for low level routines and data structures
|
||||
* for the Advanced Systems Inc. SCSI controllers chips.
|
||||
*
|
||||
* Copyright (c) 1996 Justin T. Gibbs.
|
||||
* 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 immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
/*
|
||||
* Ported from:
|
||||
* advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
|
||||
*
|
||||
* Copyright (c) 1995-1996 Advanced System Products, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that redistributions of source
|
||||
* code retain the above copyright notice and this comment without
|
||||
* modification.
|
||||
*/
|
||||
|
||||
typedef u_int8_t target_bit_vector;
|
||||
#define TARGET_BIT_VECTOR_SET -1
|
||||
#define ADV_SCSI_ID_BITS 3
|
||||
#define ADV_MAX_TID 7
|
||||
|
||||
/* Enumeration of board types */
|
||||
typedef enum {
|
||||
ADV_NONE = 0x000,
|
||||
ADV_ISA = 0x001,
|
||||
ADV_ISAPNP = 0x003,
|
||||
ADV_VL = 0x004,
|
||||
ADV_EISA = 0x008,
|
||||
ADV_PCI = 0x010
|
||||
}adv_btype;
|
||||
|
||||
typedef enum {
|
||||
ADV_STATE_NONE = 0x000
|
||||
}adv_state;
|
||||
|
||||
#define ADV_SYN_XFER_NO 8
|
||||
#define ADV_SYN_MAX_OFFSET 0x0F
|
||||
#define ADV_DEF_SDTR_OFFSET 0x0F
|
||||
#define ADV_DEF_SDTR_INDEX 0x00
|
||||
#define ADV_OVERRUN_BSIZE 0x00000048
|
||||
#define ADV_MAX_CDB_LEN 12
|
||||
#define ADV_MAX_SENSE_LEN 32
|
||||
#define ADV_MIN_SENSE_LEN 14
|
||||
|
||||
#define ADV_TIDLUN_TO_IX(tid, lun) ((tid) | ((lun) << ADV_SCSI_ID_BITS) )
|
||||
#define ADV_TID_TO_TARGET_ID(tid) (0x01 << (tid))
|
||||
#define ADV_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ADV_MAX_TID))
|
||||
#define ADV_TIX_TO_TID(tix) ((tix) & ADV_MAX_TID)
|
||||
#define ADV_TID_TO_TIX(tid) ((tid) & ADV_MAX_TID)
|
||||
#define ADV_TIX_TO_LUN(tix) (((tix) >> ADV_SCSI_ID_BITS) & ADV_MAX_LUN )
|
||||
|
||||
#define ADV_INB(adv, offset) \
|
||||
inb((adv)->iobase + (offset))
|
||||
#define ADV_INW(adv, offset) \
|
||||
inw((adv)->iobase + (offset))
|
||||
#define ADV_INSB(adv, offset, valp, size) \
|
||||
insb((adv)->iobase + (offset), (valp), (size))
|
||||
#define ADV_INSW(adv, offset, valp, size) \
|
||||
insw((adv)->iobase + (offset), (valp), (size))
|
||||
#define ADV_INSL(adv, offset, valp, size) \
|
||||
insl((adv)->iobase + (offset), (valp), (size))
|
||||
#define ADV_OUTB(adv, offset, val) \
|
||||
outb((adv)->iobase + (offset), (val))
|
||||
#define ADV_OUTW(adv, offset, val) \
|
||||
outw((adv)->iobase + (offset), (val))
|
||||
#define ADV_OUTSB(adv, offset, valp, size) \
|
||||
outsb((adv)->iobase + (offset), (valp), (size))
|
||||
#define ADV_OUTSW(adv, offset, valp, size) \
|
||||
outsw((adv)->iobase + (offset), (valp), (size))
|
||||
#define ADV_OUTSL(adv, offset, valp, size) \
|
||||
outsl((adv)->iobase + (offset), (valp), (size))
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* PnP port addresses
|
||||
* I believe that these are standard PnP address and should be replaced
|
||||
* by the values in a central ISA PnP header file when we get one.
|
||||
*/
|
||||
#define ADV_ISA_PNP_PORT_ADDR (0x279)
|
||||
#define ADV_ISA_PNP_PORT_WRITE (ADV_ISA_PNP_PORT_ADDR+0x800)
|
||||
|
||||
/*
|
||||
* Board Signatures
|
||||
*/
|
||||
#define ADV_SIGNATURE_WORD 0x0000
|
||||
#define ADV_1000_ID0W 0x04C1
|
||||
#define ADV_1000_ID0W_FIX 0x00C1
|
||||
|
||||
#define ADV_SIGNATURE_BYTE 0x0001
|
||||
#define ADV_1000_ID1B 0x25
|
||||
|
||||
/*
|
||||
* Chip Revision Number
|
||||
*/
|
||||
#define ADV_NONEISA_CHIP_REVISION 0x0003
|
||||
#define ADV_CHIP_MIN_VER_VL 0x01
|
||||
#define ADV_CHIP_MAX_VER_VL 0x07
|
||||
|
||||
#define ADV_CHIP_MIN_VER_PCI 0x09
|
||||
#define ADV_CHIP_MAX_VER_PCI 0x0F
|
||||
#define ADV_CHIP_VER_PCI_BIT 0x08
|
||||
|
||||
#define ADV_CHIP_MIN_VER_ISA 0x11
|
||||
#define ADV_CHIP_MIN_VER_ISA_PNP 0x21
|
||||
#define ADV_CHIP_MAX_VER_ISA 0x27
|
||||
#define ADV_CHIP_VER_ISA_BIT 0x30
|
||||
#define ADV_CHIP_VER_ISAPNP_BIT 0x20
|
||||
|
||||
#define ADV_CHIP_VER_ASYN_BUG 0x21
|
||||
|
||||
#define ADV_CHIP_MIN_VER_EISA 0x41
|
||||
#define ADV_CHIP_MAX_VER_EISA 0x47
|
||||
#define ADV_CHIP_VER_EISA_BIT 0x40
|
||||
|
||||
#define ADV_HALTCODE_W 0x0040
|
||||
#define ADV_STOP_CODE_B 0x0034
|
||||
#define ADV_STOP_REQ_RISC_STOP 0x01
|
||||
#define ADV_STOP_ACK_RISC_STOP 0x03
|
||||
|
||||
#define ADV_CHIP_CTRL 0x000F
|
||||
#define ADV_CC_CHIP_RESET 0x80
|
||||
#define ADV_CC_SCSI_RESET 0x40
|
||||
#define ADV_CC_HALT 0x20
|
||||
#define ADV_CC_SINGLE_STEP 0x10
|
||||
#define ADV_CC_TEST 0x04
|
||||
#define ADV_CC_BANK_ONE 0x02
|
||||
#define ADV_CC_DIAG 0x01
|
||||
|
||||
#define ADV_CHIP_STATUS 0x000E
|
||||
#define ADV_CSW_TEST1 0x8000
|
||||
#define ADV_CSW_AUTO_CONFIG 0x4000
|
||||
#define ADV_CSW_RESERVED1 0x2000
|
||||
#define ADV_CSW_IRQ_WRITTEN 0x1000
|
||||
#define ADV_CSW_33MHZ_SELECTED 0x0800
|
||||
#define ADV_CSW_TEST2 0x0400
|
||||
#define ADV_CSW_TEST3 0x0200
|
||||
#define ADV_CSW_RESERVED2 0x0100
|
||||
#define ADV_CSW_DMA_DONE 0x0080
|
||||
#define ADV_CSW_FIFO_RDY 0x0040
|
||||
#define ADV_CSW_EEP_READ_DONE 0x0020
|
||||
#define ADV_CSW_HALTED 0x0010
|
||||
#define ADV_CSW_SCSI_RESET_ACTIVE 0x0008
|
||||
#define ADV_CSW_PARITY_ERR 0x0004
|
||||
#define ADV_CSW_SCSI_RESET_LATCH 0x0002
|
||||
#define ADV_CSW_INT_PENDING 0x0001
|
||||
/*
|
||||
* XXX I don't understand the relevence of the naming
|
||||
* convention change here. What does CIW stand for?
|
||||
* Perhaps this is to differentiate read and write
|
||||
* values?
|
||||
*/
|
||||
#define ADV_CIW_INT_ACK 0x0100
|
||||
#define ADV_CIW_TEST1 0x0200
|
||||
#define ADV_CIW_TEST2 0x0400
|
||||
#define ADV_CIW_SEL_33MHZ 0x0800
|
||||
#define ADV_CIW_IRQ_ACT 0x1000
|
||||
|
||||
#define ADV_REG_IH 0x0002
|
||||
#define ADV_INS_HALTINT 0x6281
|
||||
#define ADV_INS_HALT 0x6280
|
||||
#define ADV_INS_SINT 0x6200
|
||||
#define ADV_INS_RFLAG_WTM 0x7380
|
||||
|
||||
|
||||
#define ADV_REG_SC 0x0009
|
||||
|
||||
#define ADV_REG_PROG_COUNTER 0x000C
|
||||
#define ADV_MCODE_START_ADDR 0x0080
|
||||
|
||||
#define ADV_CONFIG_LSW 0x0002
|
||||
#define ADV_CFG_LSW_HOST_INT_ON 0x0020
|
||||
#define ADV_CFG_LSW_BIOS_ON 0x0040
|
||||
#define ADV_CFG_LSW_VERA_BURST_ON 0x0080
|
||||
#define ADV_CFG_LSW_SCSI_PARITY_ON 0x0800
|
||||
|
||||
#define ADV_CONFIG_MSW 0x0004
|
||||
#define ADV_CFG_MSW_SCSI_TARGET_ON 0x0080
|
||||
#define ADV_CFG_MSW__LRAM_8BITS_ON 0x0800
|
||||
#define ADV_CFG_MSW_CLR_MASK 0xF0C0
|
||||
|
||||
|
||||
#define ADV_EEPROM_DATA 0x0006
|
||||
|
||||
#define ADV_EEPROM_CMD 0x0007
|
||||
#define ADV_EEPROM_CMD_READ 0x80
|
||||
#define ADV_EEPROM_CMD_WRITE 0x40
|
||||
#define ADV_EEPROM_CMD_WRITE_ENABLE 0x30
|
||||
#define ADV_EEPROM_CMD_WRITE_DISABLE 0x00
|
||||
|
||||
/*
|
||||
* EEPROM routine constants
|
||||
* XXX What about wide controllers?
|
||||
* Surely they have space for 8 more targets.
|
||||
*/
|
||||
#define ADV_EEPROM_CFG_BEG_VL 2
|
||||
#define ADV_EEPROM_MAX_ADDR_VL 15
|
||||
#define ADV_EEPROM_CFG_BEG 32
|
||||
#define ADV_EEPROM_MAX_ADDR 45
|
||||
#define ADV_EEPROM_MAX_RETRY 20
|
||||
|
||||
struct adv_eeprom_config {
|
||||
u_int16_t cfg_lsw;
|
||||
|
||||
u_int16_t cfg_msw;
|
||||
|
||||
u_int8_t init_sdtr;
|
||||
u_int8_t disc_enable;
|
||||
|
||||
u_int8_t use_cmd_qng;
|
||||
u_int8_t start_motor;
|
||||
|
||||
u_int8_t max_total_qng;
|
||||
u_int8_t max_tag_qng;
|
||||
|
||||
u_int8_t bios_scan;
|
||||
u_int8_t power_up_wait;
|
||||
|
||||
u_int8_t no_scam;
|
||||
u_int8_t scsi_id_dma_speed;
|
||||
#define EEPROM_SCSI_ID_MASK 0x0F
|
||||
#define EEPROM_DMA_SPEED_MASK 0xF0
|
||||
#define EEPROM_DMA_SPEED(ep) (((ep).scsi_id_dma_speed & EEPROM_DMA_SPEED_MASK) >> 8)
|
||||
#define EEPROM_SCSIID(ep) ((ep).scsi_id_dma_speed & EEPROM_SCSI_ID_MASK)
|
||||
#define EEPROM_SET_SCSIID(ep, id) ((ep).scsi_id_dma_speed &= EEPROM_SCSI_ID_MASK; \
|
||||
(ep).scsi_id_dma_speed |= ((id) & EEPROM_SCSI_ID_MASK))
|
||||
/* XXX What about wide controllers??? */
|
||||
u_int8_t sdtr_data[8];
|
||||
u_int8_t adapter_info[6];
|
||||
|
||||
u_int16_t cntl;
|
||||
|
||||
u_int16_t chksum;
|
||||
};
|
||||
|
||||
/*
|
||||
* Instruction data and code segment addresses,
|
||||
* and transaction address translation (queues).
|
||||
* All addresses refer to on board LRAM.
|
||||
*/
|
||||
#define ADV_DATA_SEC_BEG 0x0080
|
||||
#define ADV_DATA_SEC_END 0x0080
|
||||
#define ADV_CODE_SEC_BEG 0x0080
|
||||
#define ADV_CODE_SEC_END 0x0080
|
||||
#define ADV_QADR_BEG 0x4000
|
||||
#define ADV_QADR_END 0x7FFF
|
||||
#define ADV_QLAST_ADR 0x7FC0
|
||||
#define ADV_QBLK_SIZE 0x40
|
||||
#define ADV_BIOS_DATA_QBEG 0xF8
|
||||
#define ADV_MAX_QNO 0xF8
|
||||
#define ADV_QADR_USED (ADV_MAX_QNO * 64)
|
||||
#define ADV_QNO_TO_QADDR(q_no) ((ADV_QADR_BEG) + ((u_int16_t)(q_no) << 6))
|
||||
|
||||
#define ADV_MIN_ACTIVE_QNO 0x01
|
||||
#define ADV_QLINK_END 0xFF
|
||||
|
||||
#define ADV_MAX_SG_QUEUE 5
|
||||
#define ADV_SG_LIST_PER_Q 7
|
||||
#define ADV_MAX_SG_LIST (1 + ((ADV_SG_LIST_PER_Q) * (ADV_MAX_SG_QUEUE)))
|
||||
|
||||
#define ADV_MIN_REMAIN_Q 0x02
|
||||
#define ADV_DEF_MAX_TOTAL_QNG 0x40
|
||||
#define ADV_MIN_TAG_Q_PER_DVC 0x04
|
||||
#define ADV_DEF_TAG_Q_PER_DVC 0x04
|
||||
#define ADV_MIN_FREE_Q ADV_MIN_REMAIN_Q
|
||||
#define ADV_MIN_TOTAL_QNG ((ADV_MAX_SG_QUEUE)+(ADV_MIN_FREE_Q))
|
||||
#define ADV_MAX_TOTAL_QNG 240
|
||||
#define ADV_MAX_INRAM_TAG_QNG 16
|
||||
#define ADV_MAX_PCI_INRAM_TOTAL_QNG 20
|
||||
|
||||
#define ADV_DEF_IRQ_NO 10
|
||||
#define ADV_MAX_IRQ_NO 15
|
||||
#define ADV_MIN_IRQ_NO 10
|
||||
|
||||
#define ADV_SCSIQ_CPY_BEG 4
|
||||
#define ADV_SCSIQ_SGHD_CPY_BEG 2
|
||||
|
||||
#define ADV_SCSIQ_B_FWD 0
|
||||
#define ADV_SCSIQ_B_BWD 1
|
||||
|
||||
#define ADV_SCSIQ_B_STATUS 2
|
||||
#define ADV_SCSIQ_B_QNO 3
|
||||
|
||||
#define ADV_SCSIQ_B_CNTL 4
|
||||
#define ADV_SCSIQ_B_SG_QUEUE_CNT 5
|
||||
|
||||
#define ADV_LRAM_ADDR 0x000A
|
||||
#define ADV_LRAM_DATA 0x0008
|
||||
|
||||
#define ADV_SYN_OFFSET 0x000B
|
||||
|
||||
/* LRAM Offsets */
|
||||
#define ADVV_MSGOUT_BEG 0x0000
|
||||
#define ADVV_MSGOUT_SDTR_PERIOD (ADVV_MSGOUT_BEG+3)
|
||||
#define ADVV_MSGOUT_SDTR_OFFSET (ADVV_MSGOUT_BEG+4)
|
||||
|
||||
#define ADVV_MSGIN_BEG (ADVV_MSGOUT_BEG+8)
|
||||
#define ADVV_MSGIN_SDTR_PERIOD (ADVV_MSGIN_BEG+3)
|
||||
#define ADVV_MSGIN_SDTR_OFFSET (ADVV_MSGIN_BEG+4)
|
||||
|
||||
#define ADVV_SDTR_DATA_BEG (ADVV_MSGIN_BEG+8)
|
||||
#define ADVV_SDTR_DONE_BEG (ADVV_SDTR_DATA_BEG+8)
|
||||
#define ADVV_MAX_DVC_QNG_BEG 0x0020
|
||||
|
||||
#define ADVV_ASCDVC_ERR_CODE_W 0x0030
|
||||
#define ADVV_MCODE_CHKSUM_W 0x0032
|
||||
#define ADVV_MCODE_SIZE_W 0x0034
|
||||
#define ADVV_STOP_CODE_B 0x0036
|
||||
#define ADVV_DVC_ERR_CODE_B 0x0037
|
||||
|
||||
#define ADVV_OVERRUN_PADDR_D 0x0038
|
||||
#define ADVV_OVERRUN_BSIZE_D 0x003C
|
||||
|
||||
#define ADVV_HALTCODE_W 0x0040
|
||||
#define ADV_HALT_EXTMSG_IN 0x8000
|
||||
#define ADV_HALT_CHK_CONDITION 0x8100
|
||||
#define ADV_HALT_SS_QUEUE_FULL 0x8200
|
||||
#define ADV_HALT_SDTR_REJECTED 0x4000
|
||||
|
||||
#define ADVV_CHKSUM_W 0x0042
|
||||
#define ADVV_MC_DATE_W 0x0044
|
||||
#define ADVV_MC_VER_W 0x0046
|
||||
#define ADVV_NEXTRDY_B 0x0048
|
||||
#define ADVV_DONENEXT_B 0x0049
|
||||
#define ADVV_USE_TAGGED_QNG_B 0x004A
|
||||
#define ADVV_SCSIBUSY_B 0x004B
|
||||
#define ADVV_CDBCNT_B 0x004C
|
||||
#define ADVV_CURCDB_B 0x004D
|
||||
#define ADVV_RCLUN_B 0x004E
|
||||
#define ADVV_BUSY_QHEAD_B 0x004F
|
||||
#define ADVV_DISC1_QHEAD_B 0x0050
|
||||
|
||||
#define ADVV_DISC_ENABLE_B 0x0052
|
||||
#define ADVV_CAN_TAGGED_QNG_B 0x0053
|
||||
#define ADVV_HOSTSCSI_ID_B 0x0055
|
||||
#define ADVV_MCODE_CNTL_B 0x0056
|
||||
#define ADVV_NULL_TARGET_B 0x0057
|
||||
|
||||
#define ADVV_FREE_Q_HEAD_W 0x0058
|
||||
#define ADVV_DONE_Q_TAIL_W 0x005A
|
||||
#define ADVV_FREE_Q_HEAD_B (ADVV_FREE_Q_HEAD_W+1)
|
||||
#define ADVV_DONE_Q_TAIL_B (ADVV_DONE_Q_TAIL_W+1)
|
||||
|
||||
#define ADVV_HOST_FLAG_B 0x005D
|
||||
#define ADV_HOST_FLAG_IN_ISR 0x01
|
||||
#define ADV_HOST_FLAG_ACK_INT 0x02
|
||||
|
||||
|
||||
#define ADVV_TOTAL_READY_Q_B 0x0064
|
||||
#define ADVV_VER_SERIAL_B 0x0065
|
||||
#define ADVV_HALTCODE_SAVED_W 0x0066
|
||||
#define ADVV_WTM_FLAG_B 0x0068
|
||||
#define ADVV_RISC_FLAG_B 0x006A
|
||||
#define ADV_RISC_FLAG_GEN_INT 0x01
|
||||
#define ADV_RISC_FLAG_REQ_SG_LIST 0x02
|
||||
|
||||
#define ADVV_REQ_SG_LIST_QP 0x006B
|
||||
struct adv_softc
|
||||
{
|
||||
/* The overrun buffer must be quad word aligned */
|
||||
u_int8_t overrun_buf[ADV_OVERRUN_BSIZE];
|
||||
int unit;
|
||||
u_int32_t iobase;
|
||||
adv_btype type;
|
||||
target_bit_vector needs_async_bug_fix;
|
||||
target_bit_vector initiate_sdtr;
|
||||
target_bit_vector sdtr_done;
|
||||
target_bit_vector cmd_qng_enabled;
|
||||
target_bit_vector unit_not_ready;
|
||||
target_bit_vector start_motor;
|
||||
target_bit_vector no_scam;
|
||||
target_bit_vector disc_enable;
|
||||
u_int16_t control;
|
||||
#define ADV_CNTL_INITIATOR 0x0001
|
||||
#define ADV_CNTL_BIOS_GT_1GB 0x0002
|
||||
#define ADV_CNTL_BIOS_GT_2_DISK 0x0004
|
||||
#define ADV_CNTL_BIOS_REMOVABLE 0x0008
|
||||
#define ADV_CNTL_NO_SCAM 0x0010
|
||||
#define ADV_CNTL_NO_PCI_FIX_ASYN_XFER 0x0020
|
||||
#define ADV_CNTL_INT_MULTI_Q 0x0080
|
||||
#define ADV_CNTL_NO_LUN_SUPPORT 0x0040
|
||||
#define ADV_CNTL_NO_VERIFY_COPY 0x0100
|
||||
#define ADV_CNTL_RESET_SCSI 0x0200
|
||||
#define ADV_CNTL_INIT_INQUIRY 0x0400
|
||||
#define ADV_CNTL_INIT_VERBOSE 0x0800
|
||||
#define ADV_CNTL_SCSI_PARITY 0x1000
|
||||
#define ADV_CNTL_BURST_MODE 0x2000
|
||||
#define ADV_CNTL_USE_8_IOP_BASE 0x4000
|
||||
|
||||
u_int16_t bug_fix_control;
|
||||
#define ADV_BUG_FIX_ADD_ONE_BYTE 0x0001
|
||||
|
||||
adv_state state;
|
||||
u_int32_t max_dma_count;
|
||||
u_int8_t isa_dma_speed;
|
||||
u_int8_t scsi_id;
|
||||
u_int8_t chip_version;
|
||||
u_int8_t max_tags_per_target;
|
||||
u_int8_t max_openings;
|
||||
u_int8_t cur_active;
|
||||
u_int8_t openings_needed;
|
||||
u_int8_t sdtr_data[16];
|
||||
struct scsi_sense_data *sense_buffers;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structures for talking to the RISC engine.
|
||||
*/
|
||||
struct adv_scsiq_1 {
|
||||
u_int8_t status;
|
||||
#define QS_FREE 0x00
|
||||
#define QS_READY 0x01
|
||||
#define QS_DISC1 0x02
|
||||
#define QS_DISC2 0x04
|
||||
#define QS_BUSY 0x08
|
||||
#define QS_ABORTED 0x40
|
||||
#define QS_DONE 0x80
|
||||
|
||||
u_int8_t q_no; /*
|
||||
* Queue ID of the first queue
|
||||
* used in this transaction.
|
||||
*/
|
||||
u_int8_t cntl;
|
||||
#define QC_NO_CALLBACK 0x01
|
||||
#define QC_SG_SWAP_QUEUE 0x02
|
||||
#define QC_SG_HEAD 0x04
|
||||
#define QC_DATA_IN 0x08
|
||||
#define QC_DATA_OUT 0x10
|
||||
#define QC_URGENT 0x20
|
||||
#define QC_MSG_OUT 0x40
|
||||
#define QC_REQ_SENSE 0x80
|
||||
|
||||
u_int8_t sg_queue_cnt; /* Number of SG entries */
|
||||
|
||||
u_int8_t target_id; /* target id as a bit vector */
|
||||
u_int8_t target_lun; /* LUN - taken from our xs */
|
||||
|
||||
u_int32_t data_addr; /*
|
||||
* physical addres of first
|
||||
* (possibly only) segment
|
||||
* to transfer.
|
||||
*/
|
||||
u_int32_t data_cnt; /*
|
||||
* byte count of the first
|
||||
* (possibly only) segment
|
||||
* to transfer.
|
||||
*/
|
||||
u_int32_t sense_addr; /*
|
||||
* physical address of the sense
|
||||
* buffer.
|
||||
*/
|
||||
u_int8_t sense_len; /* length of sense buffer */
|
||||
u_int8_t user_def;
|
||||
};
|
||||
|
||||
struct adv_scsiq_2 {
|
||||
u_int32_t xs_ptr; /* Pointer to our scsi_xfer */
|
||||
u_int8_t target_ix; /* Combined TID and LUN */
|
||||
|
||||
u_int8_t flag;
|
||||
u_int8_t cdb_len; /*
|
||||
* Number of bytes in the SCSI
|
||||
* command to execute.
|
||||
*/
|
||||
u_int8_t tag_code; /*
|
||||
* Tag type for this transaction
|
||||
* (SIMPLE, ORDERED, HEAD )
|
||||
*/
|
||||
#define ADV_TAG_FLAG_ADD_ONE_BYTE 0x10
|
||||
#define ADV_TAG_FLAG_ISAPNP_ADD_BYTES 0x40
|
||||
|
||||
u_int16_t vm_id;
|
||||
};
|
||||
|
||||
struct adv_scsiq_3 {
|
||||
u_int8_t done_stat;
|
||||
#define QD_IN_PROGRESS 0x00
|
||||
#define QD_NO_ERROR 0x01
|
||||
#define QD_ABORTED_BY_HOST 0x02
|
||||
#define QD_WITH_ERROR 0x04
|
||||
#define QD_INVALID_REQUEST 0x80
|
||||
#define QD_INVALID_HOST_NUM 0x81
|
||||
#define QD_INVALID_DEVICE 0x82
|
||||
#define QD_ERR_INTERNAL 0xFF
|
||||
|
||||
u_int8_t host_stat;
|
||||
#define QHSTA_NO_ERROR 0x00
|
||||
#define QHSTA_M_SEL_TIMEOUT 0x11
|
||||
#define QHSTA_M_DATA_OVER_RUN 0x12
|
||||
#define QHSTA_M_DATA_UNDER_RUN 0x12
|
||||
#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
|
||||
#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
|
||||
|
||||
#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
|
||||
#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
|
||||
#define QHSTA_D_HOST_ABORT_FAILED 0x23
|
||||
#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
|
||||
#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
|
||||
#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
|
||||
|
||||
#define QHSTA_M_WTM_TIMEOUT 0x41
|
||||
#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
|
||||
#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
|
||||
#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
|
||||
#define QHSTA_M_TARGET_STATUS_BUSY 0x45
|
||||
#define QHSTA_M_BAD_TAG_CODE 0x46
|
||||
|
||||
#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
|
||||
|
||||
#define QHSTA_D_LRAM_CMP_ERROR 0x81
|
||||
|
||||
#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
|
||||
|
||||
u_int8_t scsi_stat;
|
||||
u_int8_t scsi_msg;
|
||||
};
|
||||
|
||||
struct adv_scsiq_4 {
|
||||
u_int8_t cdb[ADV_MAX_CDB_LEN];
|
||||
u_int8_t y_first_sg_list_qp;
|
||||
u_int8_t y_working_sg_qp;
|
||||
u_int8_t y_working_sg_ix;
|
||||
u_int8_t y_cntl;
|
||||
u_int16_t x_req_count;
|
||||
u_int16_t x_reconnect_rtn;
|
||||
u_int32_t x_saved_data_addr;
|
||||
u_int32_t x_saved_data_cnt;
|
||||
};
|
||||
|
||||
struct adv_q_done_info {
|
||||
struct adv_scsiq_2 d2;
|
||||
struct adv_scsiq_3 d3;
|
||||
u_int8_t q_status;
|
||||
u_int8_t q_no;
|
||||
u_int8_t cntl;
|
||||
u_int8_t sense_len;
|
||||
u_int8_t user_def;
|
||||
u_int8_t res;
|
||||
u_int32_t remain_bytes;
|
||||
};
|
||||
|
||||
struct adv_sg_entry {
|
||||
u_int32_t addr;
|
||||
u_int32_t bytes;
|
||||
};
|
||||
|
||||
struct adv_sg_head {
|
||||
u_int8_t entry_cnt; /* Number of SG entries in this list */
|
||||
|
||||
u_int8_t queue_cnt; /*
|
||||
* Number of queues required to store
|
||||
* entry_cnt SG entries.
|
||||
*/
|
||||
|
||||
u_int8_t entry_to_copy; /*
|
||||
* Number of SG entries to copy to the
|
||||
* board.
|
||||
*/
|
||||
u_int8_t res;
|
||||
struct adv_sg_entry sg_list[ADV_MAX_SG_LIST];
|
||||
};
|
||||
|
||||
#define ADV_MIN_SG_LIST 2
|
||||
|
||||
struct adv_min_sg_head {
|
||||
u_int8_t entry_cnt;
|
||||
|
||||
u_int8_t queue_cnt;
|
||||
|
||||
u_int8_t entry_to_copy;
|
||||
u_int8_t res;
|
||||
struct adv_sg_entry sg_list[ADV_MIN_SG_LIST];
|
||||
};
|
||||
|
||||
#define QCX_SORT (0x0001)
|
||||
#define QCX_COALEASE (0x0002)
|
||||
|
||||
#if CC_LINK_BUSY_Q
|
||||
struct asc_ext_scsi_q {
|
||||
u_int32_t lba;
|
||||
u_int16_t lba_len;
|
||||
struct adv_scsi_q *next;
|
||||
struct adv_scsi_q *join;
|
||||
u_int16_t cntl;
|
||||
u_int16_t buffer_id;
|
||||
u_int8_t q_required;
|
||||
u_int8_t res;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct adv_scsi_q {
|
||||
struct adv_scsiq_1 q1;
|
||||
struct adv_scsiq_2 q2;
|
||||
struct scsi_generic *cdbptr; /*
|
||||
* Pointer to the SCSI command
|
||||
* to execute.
|
||||
*/
|
||||
|
||||
struct adv_sg_head *sg_head; /*
|
||||
* Pointer to possible SG list
|
||||
*/
|
||||
#if CC_LINK_BUSY_Q
|
||||
struct adv_ext_scsi_q ext;
|
||||
#endif
|
||||
|
||||
};
|
||||
#define ADV_SCSIQ_D_DATA_ADDR 8
|
||||
#define ADV_SCSIQ_D_DATA_CNT 12
|
||||
#define ADV_SCSIQ_B_SENSE_LEN 20
|
||||
#define ADV_SCSIQ_DONE_INFO_BEG 22
|
||||
#define ADV_SCSIQ_D_SRBPTR 22
|
||||
#define ADV_SCSIQ_B_TARGET_IX 26
|
||||
#define ADV_SCSIQ_B_CDB_LEN 28
|
||||
#define ADV_SCSIQ_B_TAG_CODE 29
|
||||
#define ADV_SCSIQ_W_VM_ID 30
|
||||
#define ADV_SCSIQ_DONE_STATUS 32
|
||||
#define ADV_SCSIQ_HOST_STATUS 33
|
||||
#define ADV_SCSIQ_SCSI_STATUS 34
|
||||
#define ADV_SCSIQ_CDB_BEG 36
|
||||
#define ADV_SCSIQ_DW_REMAIN_XFER_ADDR 56
|
||||
#define ADV_SCSIQ_DW_REMAIN_XFER_CNT 60
|
||||
#define ADV_SCSIQ_B_SG_WK_QP 49
|
||||
#define ADV_SCSIQ_B_SG_WK_IX 50
|
||||
#define ADV_SCSIQ_W_REQ_COUNT 52
|
||||
#define ADV_SCSIQ_B_LIST_CNT 6
|
||||
#define ADV_SCSIQ_B_CUR_LIST_CNT 7
|
||||
|
||||
|
||||
struct adv_scsi_req_q {
|
||||
struct adv_scsiq_1 r1;
|
||||
struct adv_scsiq_2 r2;
|
||||
u_int8_t *cdbptr;
|
||||
struct adv_sg_head *sg_head;
|
||||
|
||||
#if CC_LINK_BUSY_Q
|
||||
struct adv_ext_scsi_q ext;
|
||||
#endif
|
||||
|
||||
u_int8_t *sense_ptr;
|
||||
|
||||
struct adv_scsiq_3 r3;
|
||||
u_int8_t cdb[ADV_MAX_CDB_LEN];
|
||||
u_int8_t sense[ADV_MIN_SENSE_LEN];
|
||||
};
|
||||
|
||||
struct adv_risc_q {
|
||||
u_int8_t fwd;
|
||||
u_int8_t bwd;
|
||||
struct adv_scsiq_1 i1;
|
||||
struct adv_scsiq_2 i2;
|
||||
struct adv_scsiq_3 i3;
|
||||
struct adv_scsiq_4 i4;
|
||||
};
|
||||
|
||||
struct adv_sg_list_q {
|
||||
u_int8_t seq_no;
|
||||
u_int8_t q_no;
|
||||
u_int8_t cntl;
|
||||
#define QCSG_SG_XFER_LIST 0x02
|
||||
#define QCSG_SG_XFER_MORE 0x04
|
||||
#define QCSG_SG_XFER_END 0x08
|
||||
|
||||
u_int8_t sg_head_qp;
|
||||
u_int8_t sg_list_cnt;
|
||||
u_int8_t sg_cur_list_cnt;
|
||||
};
|
||||
#define ADV_SGQ_B_SG_CNTL 4
|
||||
#define ADV_SGQ_B_SG_HEAD_QP 5
|
||||
#define ADV_SGQ_B_SG_LIST_CNT 6
|
||||
#define ADV_SGQ_B_SG_CUR_LIST_CNT 7
|
||||
#define ADV_SGQ_LIST_BEG 8
|
||||
|
||||
struct asc_risc_sg_list_q {
|
||||
u_int8_t fwd;
|
||||
u_int8_t bwd;
|
||||
struct adv_sg_list_q sg;
|
||||
struct adv_sg_entry sg_list[7];
|
||||
};
|
||||
|
||||
|
||||
/* LRAM routines */
|
||||
u_int8_t adv_read_lram_8 __P((struct adv_softc *adv, u_int16_t addr));
|
||||
void adv_write_lram_8 __P((struct adv_softc *adv, u_int16_t addr,
|
||||
u_int8_t value));
|
||||
u_int16_t adv_read_lram_16 __P((struct adv_softc *adv, u_int16_t addr));
|
||||
void adv_write_lram_16 __P((struct adv_softc *adv, u_int16_t addr,
|
||||
u_int16_t value));
|
||||
|
||||
/* Intialization */
|
||||
void adv_get_board_type __P((struct adv_softc *adv));
|
||||
u_int16_t adv_get_eeprom_config __P((struct adv_softc *adv,
|
||||
struct adv_eeprom_config *eeprom_config));
|
||||
int adv_set_eeprom_config __P((struct adv_softc *adv,
|
||||
struct adv_eeprom_config *eeprom_config));
|
||||
int adv_reset_chip_and_scsi_bus __P((struct adv_softc *adv));
|
||||
int adv_test_external_lram __P((struct adv_softc* adv));
|
||||
int adv_init_lram_and_mcode __P((struct adv_softc *adv));
|
||||
u_int8_t adv_get_chip_irq __P((struct adv_softc *adv));
|
||||
u_int8_t adv_set_chip_irq __P((struct adv_softc *adv, u_int8_t irq_no));
|
||||
|
||||
/* Queue handling and execution */
|
||||
int adv_execute_scsi_queue __P((struct adv_softc *adv, struct adv_scsi_q *scsiq));
|
||||
u_int8_t adv_copy_lram_doneq __P((struct adv_softc *adv, u_int16_t q_addr,
|
||||
struct adv_q_done_info *scsiq, u_int32_t max_dma_count));
|
||||
|
||||
/* Chip Control */
|
||||
int adv_stop_execution __P((struct adv_softc *adv));
|
||||
int adv_is_chip_halted __P((struct adv_softc *adv));
|
||||
|
||||
/* Interrupt processing */
|
||||
void adv_ack_interrupt __P((struct adv_softc *adv));
|
||||
void adv_isr_chip_halted __P((struct adv_softc *adv));
|
166
sys/dev/advansys/advmcode.c
Normal file
166
sys/dev/advansys/advmcode.c
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Downloadable microcode for Advanced Systems Inc. SCSI controllers
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Obtained from:
|
||||
* advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
|
||||
*
|
||||
* Copyright (c) 1995-1996 Advanced System Products, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that redistributions of source
|
||||
* code retain the above copyright notice and this comment without
|
||||
* modification.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
u_int8_t adv_mcode[] =
|
||||
{
|
||||
0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xDD, 0x0A, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x23, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x88, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC8, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
|
||||
0xB6, 0x00, 0x36, 0x00, 0x06, 0xD6, 0x0D, 0xD2, 0x15, 0xDE, 0x12, 0xDA, 0x00, 0xA2, 0xC8, 0x00,
|
||||
0x92, 0x80, 0xE0, 0x97, 0x50, 0x00, 0xF5, 0x00, 0x0A, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00,
|
||||
0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00, 0x0A, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
|
||||
0x80, 0x62, 0x92, 0x80, 0x00, 0x62, 0x92, 0x80, 0x00, 0x46, 0x17, 0xEE, 0x13, 0xEA, 0x02, 0x01,
|
||||
0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDC, 0x00, 0x68, 0x97, 0x7F, 0x23, 0x04, 0x61,
|
||||
0x84, 0x01, 0xB2, 0x84, 0xCF, 0xC1, 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xE8, 0x01,
|
||||
0x68, 0x97, 0xD4, 0x81, 0x00, 0x33, 0x02, 0x00, 0x82, 0x88, 0x80, 0x73, 0x80, 0x77, 0x00, 0x01,
|
||||
0x01, 0xA1, 0x08, 0x01, 0x4F, 0x00, 0x46, 0x97, 0x07, 0xA6, 0x12, 0x01, 0x00, 0x33, 0x03, 0x00,
|
||||
0x82, 0x88, 0x03, 0x03, 0x03, 0xDE, 0x00, 0x33, 0x05, 0x00, 0x82, 0x88, 0xCE, 0x00, 0x69, 0x60,
|
||||
0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x86, 0x01, 0x80, 0x63, 0x07, 0xA6, 0x32, 0x01,
|
||||
0x86, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x42, 0x01, 0x00, 0x33, 0x04, 0x00,
|
||||
0x82, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x2A, 0x98, 0x4D, 0x04, 0xD0, 0x84,
|
||||
0x05, 0xD8, 0x0D, 0x23, 0x2A, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xB8, 0x88, 0xFB, 0x23, 0x02, 0x61,
|
||||
0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x70, 0x01, 0x00, 0x33, 0x0A, 0x00, 0x82, 0x88,
|
||||
0x4E, 0x00, 0x07, 0xA3, 0x7C, 0x01, 0x00, 0x33, 0x0B, 0x00, 0x82, 0x88, 0xCD, 0x04, 0x36, 0x2D,
|
||||
0x00, 0x33, 0x1A, 0x00, 0x82, 0x88, 0x50, 0x04, 0x96, 0x81, 0x06, 0xAB, 0x90, 0x01, 0x96, 0x81,
|
||||
0x4E, 0x00, 0x07, 0xA3, 0xA0, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x4A, 0x01, 0x00, 0x05, 0x8A, 0x81,
|
||||
0x08, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xCC, 0x81,
|
||||
0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xC2, 0x01,
|
||||
0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0x82, 0x88, 0x06, 0x23, 0x2A, 0x98,
|
||||
0xCD, 0x04, 0xB2, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xE2, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xE8, 0x01,
|
||||
0xB2, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xB2, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, 0x00, 0xA2,
|
||||
0x10, 0x02, 0x04, 0x01, 0x0D, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x46, 0x97, 0x0A, 0x82,
|
||||
0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x24, 0x97, 0x48, 0x04, 0xFF, 0x23, 0x84, 0x80,
|
||||
0xB2, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
|
||||
0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x66, 0xEB, 0x11, 0x23, 0xB8, 0x88, 0xC6, 0x97, 0xFA, 0x80,
|
||||
0x80, 0x73, 0x80, 0x77, 0x06, 0xA6, 0x3E, 0x02, 0x00, 0x33, 0x31, 0x00, 0x82, 0x88, 0x04, 0x01,
|
||||
0x03, 0xD8, 0x74, 0x98, 0x02, 0x96, 0x50, 0x82, 0xA2, 0x95, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
|
||||
0xB6, 0x2D, 0x02, 0xA6, 0x7A, 0x02, 0x07, 0xA6, 0x68, 0x02, 0x06, 0xA6, 0x6C, 0x02, 0x03, 0xA6,
|
||||
0x70, 0x02, 0x00, 0x33, 0x10, 0x00, 0x82, 0x88, 0x4A, 0x95, 0x52, 0x82, 0xF8, 0x95, 0x52, 0x82,
|
||||
0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x16, 0x84, 0x04, 0x01, 0x0C, 0xDC, 0xE0, 0x23,
|
||||
0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23,
|
||||
0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAC, 0x02, 0x07, 0xA6,
|
||||
0x68, 0x02, 0x06, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x12, 0x00, 0x82, 0x88, 0x00, 0x0E, 0x80, 0x63,
|
||||
0x00, 0x43, 0x00, 0xA0, 0x9A, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61,
|
||||
0x84, 0x01, 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
|
||||
0xEC, 0x82, 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE4, 0x02, 0x04, 0x01, 0x8E, 0xC8, 0x00, 0x33,
|
||||
0x1F, 0x00, 0x82, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x40, 0x98, 0xB6, 0x2D,
|
||||
0x01, 0xA6, 0x0E, 0x03, 0x00, 0xA6, 0x1C, 0x03, 0x07, 0xA6, 0x2A, 0x03, 0x06, 0xA6, 0x2E, 0x03,
|
||||
0x03, 0xA6, 0xFA, 0x03, 0x02, 0xA6, 0x7A, 0x02, 0x00, 0x33, 0x33, 0x00, 0x82, 0x88, 0x08, 0x23,
|
||||
0xB3, 0x01, 0x04, 0x01, 0x0E, 0xD0, 0x00, 0x33, 0x14, 0x00, 0x82, 0x88, 0x10, 0x23, 0xB3, 0x01,
|
||||
0x04, 0x01, 0x07, 0xCC, 0x00, 0x33, 0x15, 0x00, 0x82, 0x88, 0x4A, 0x95, 0xF0, 0x82, 0xF8, 0x95,
|
||||
0xF0, 0x82, 0x44, 0x98, 0x80, 0x42, 0x40, 0x98, 0x48, 0xE4, 0x04, 0x01, 0x29, 0xC8, 0x31, 0x05,
|
||||
0x07, 0x01, 0x00, 0xA2, 0x72, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x48, 0x98, 0x40, 0x98,
|
||||
0x00, 0xA6, 0x34, 0x03, 0x07, 0xA6, 0x6A, 0x03, 0x03, 0xA6, 0x16, 0x04, 0x06, 0xA6, 0x6E, 0x03,
|
||||
0x01, 0xA6, 0x34, 0x03, 0x00, 0x33, 0x25, 0x00, 0x82, 0x88, 0x4A, 0x95, 0x50, 0x83, 0xF8, 0x95,
|
||||
0x50, 0x83, 0x04, 0x01, 0x0C, 0xCE, 0x03, 0xC8, 0x00, 0x33, 0x42, 0x00, 0x82, 0x88, 0x00, 0x01,
|
||||
0x05, 0x05, 0xFF, 0xA2, 0x90, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x4C, 0x83, 0x05, 0x05,
|
||||
0x01, 0xA6, 0x9A, 0x03, 0x00, 0xA6, 0xAA, 0x03, 0xF0, 0x83, 0x68, 0x98, 0x80, 0x42, 0x01, 0xA6,
|
||||
0x9A, 0x03, 0xBA, 0x83, 0x00, 0x33, 0x2F, 0x00, 0x82, 0x88, 0x68, 0x98, 0x80, 0x42, 0x00, 0xA6,
|
||||
0xAA, 0x03, 0xBA, 0x83, 0x00, 0x33, 0x26, 0x00, 0x82, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36,
|
||||
0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0xF0, 0x83, 0x04, 0xF0, 0x80, 0x6B, 0x00, 0x33,
|
||||
0x20, 0x00, 0x82, 0x88, 0x03, 0xA6, 0xEE, 0x03, 0x07, 0xA6, 0xE6, 0x03, 0x06, 0xA6, 0xEA, 0x03,
|
||||
0x00, 0x33, 0x17, 0x00, 0x82, 0x88, 0x4A, 0x95, 0xD4, 0x83, 0xF8, 0x95, 0xD4, 0x83, 0xFA, 0x83,
|
||||
0x04, 0xF0, 0x80, 0x6B, 0x00, 0x33, 0x20, 0x00, 0x82, 0x88, 0xB6, 0x2D, 0x03, 0xA6, 0x16, 0x04,
|
||||
0x07, 0xA6, 0x0E, 0x04, 0x06, 0xA6, 0x12, 0x04, 0x00, 0x33, 0x30, 0x00, 0x82, 0x88, 0x4A, 0x95,
|
||||
0xFA, 0x83, 0xF8, 0x95, 0xFA, 0x83, 0xA2, 0x0D, 0x80, 0x63, 0x07, 0xA6, 0x24, 0x04, 0x00, 0x33,
|
||||
0x18, 0x00, 0x82, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x2E, 0x04, 0x23, 0x01,
|
||||
0x00, 0xA2, 0x50, 0x04, 0x0A, 0xA0, 0x40, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00, 0x82, 0x88,
|
||||
0x0B, 0xA0, 0x4C, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00, 0x82, 0x88, 0x42, 0x23, 0xB8, 0x88,
|
||||
0x00, 0x23, 0x22, 0xA3, 0xB2, 0x04, 0x08, 0x23, 0x22, 0xA3, 0x6C, 0x04, 0x28, 0x23, 0x22, 0xA3,
|
||||
0x78, 0x04, 0x02, 0x23, 0x22, 0xA3, 0x8E, 0x04, 0x42, 0x23, 0xB8, 0x88, 0x4A, 0x00, 0x06, 0x61,
|
||||
0x00, 0xA0, 0x78, 0x04, 0x45, 0x23, 0xB8, 0x88, 0xC6, 0x97, 0x00, 0xA2, 0x8A, 0x04, 0x74, 0x98,
|
||||
0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xF6, 0x81, 0x47, 0x23, 0xB8, 0x88, 0x04, 0x01,
|
||||
0x0C, 0xDE, 0x14, 0x01, 0x00, 0xA2, 0xA6, 0x04, 0xC6, 0x97, 0x74, 0x98, 0x00, 0x33, 0x00, 0x81,
|
||||
0xC0, 0x20, 0x81, 0x62, 0x10, 0x82, 0x43, 0x23, 0xB8, 0x88, 0x04, 0x23, 0xA0, 0x01, 0x44, 0x23,
|
||||
0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xC0, 0x04, 0x00, 0x33, 0x27, 0x00, 0x82, 0x88,
|
||||
0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xC6, 0x97, 0xF4, 0x94,
|
||||
0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0xEE, 0x04, 0x00, 0x05, 0x76, 0x00,
|
||||
0x06, 0x61, 0x00, 0xA2, 0xE8, 0x04, 0xD6, 0x84, 0x08, 0x97, 0xCD, 0x04, 0xF2, 0x84, 0x48, 0x04,
|
||||
0xFF, 0x23, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x02, 0x85, 0x02, 0x23,
|
||||
0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x0E, 0x05, 0x1D, 0x01, 0x04, 0xD6, 0xFF, 0x23,
|
||||
0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01, 0x04, 0x01,
|
||||
0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00,
|
||||
0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x2E, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00, 0x5D, 0x00,
|
||||
0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xA0, 0x05, 0x03, 0x03,
|
||||
0x02, 0xA0, 0x5C, 0x05, 0x9C, 0x85, 0x00, 0x33, 0x2D, 0x00, 0x82, 0x88, 0x04, 0xA0, 0x82, 0x05,
|
||||
0x80, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x6E, 0x05, 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23,
|
||||
0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x24, 0x97, 0xD0, 0x84, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01,
|
||||
0xD0, 0x84, 0x08, 0xA0, 0x88, 0x05, 0x9C, 0x85, 0x03, 0xA0, 0x8E, 0x05, 0x9C, 0x85, 0x01, 0xA0,
|
||||
0x9A, 0x05, 0x88, 0x00, 0x80, 0x63, 0x78, 0x96, 0x4A, 0x85, 0x88, 0x86, 0x80, 0x63, 0x4A, 0x85,
|
||||
0x00, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xDE, 0x05, 0x1D, 0x01, 0x18, 0xD4, 0xC0, 0x23,
|
||||
0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0xC0, 0x05, 0x00, 0x33, 0x37, 0x00, 0x82, 0x88,
|
||||
0x1D, 0x01, 0x02, 0xD6, 0x46, 0x23, 0xB8, 0x88, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
|
||||
0xD8, 0x05, 0x00, 0x33, 0x38, 0x00, 0x82, 0x88, 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00,
|
||||
0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xF2, 0x05, 0xC0, 0x23, 0x07, 0x41,
|
||||
0x00, 0x63, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63,
|
||||
0x00, 0x63, 0x06, 0xA6, 0x14, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x02, 0xA6, 0xBC, 0x06, 0x00, 0x33,
|
||||
0x39, 0x00, 0x82, 0x88, 0x00, 0x00, 0x01, 0xA0, 0xD6, 0x06, 0xA2, 0x95, 0x83, 0x03, 0x80, 0x63,
|
||||
0x06, 0xA6, 0x28, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x00, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
|
||||
0x01, 0x00, 0x06, 0xA6, 0x40, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x33, 0x3A, 0x00, 0x82, 0x88,
|
||||
0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x32, 0x06, 0x06, 0xA6, 0x58, 0x06, 0x07, 0xA6,
|
||||
0x64, 0x06, 0x00, 0x33, 0x3B, 0x00, 0x82, 0x88, 0x80, 0x67, 0x40, 0x0E, 0x80, 0x63, 0x07, 0xA6,
|
||||
0x64, 0x06, 0x00, 0x63, 0x03, 0x03, 0x80, 0x63, 0x88, 0x00, 0x01, 0xA2, 0x78, 0x06, 0x07, 0xA2,
|
||||
0xBC, 0x06, 0x00, 0x33, 0x35, 0x00, 0x82, 0x88, 0x07, 0xA6, 0x82, 0x06, 0x00, 0x33, 0x2A, 0x00,
|
||||
0x82, 0x88, 0x03, 0x03, 0x03, 0xA2, 0x8E, 0x06, 0x07, 0x23, 0x80, 0x00, 0xC8, 0x86, 0x80, 0x63,
|
||||
0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0x9E, 0x06, 0x00, 0x33, 0x29, 0x00, 0x82, 0x88, 0x00, 0x43,
|
||||
0x00, 0xA2, 0xAA, 0x06, 0xC0, 0x0E, 0x80, 0x63, 0x94, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80,
|
||||
0xC0, 0x20, 0x81, 0x62, 0x04, 0x01, 0x08, 0xDA, 0x80, 0x63, 0x00, 0x63, 0x80, 0x67, 0x00, 0x33,
|
||||
0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x20, 0x06,
|
||||
0x00, 0x33, 0x2C, 0x00, 0x82, 0x88, 0x0C, 0xA2, 0xF0, 0x06, 0xA2, 0x95, 0x83, 0x03, 0x80, 0x63,
|
||||
0x06, 0xA6, 0xEE, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x33, 0x3D, 0x00, 0x82, 0x88, 0x00, 0x00,
|
||||
0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x06, 0x07, 0x07, 0xA6, 0x64, 0x06, 0xBF, 0x23,
|
||||
0x04, 0x61, 0x84, 0x01, 0xB2, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01,
|
||||
0xF2, 0x00, 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05,
|
||||
0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00,
|
||||
0x81, 0x01, 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00,
|
||||
0x80, 0x01, 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00,
|
||||
0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04,
|
||||
0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01,
|
||||
0xA2, 0x01, 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0x86, 0x07,
|
||||
0x00, 0x33, 0x07, 0x00, 0x82, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00,
|
||||
0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2,
|
||||
0xA6, 0x07, 0x00, 0x05, 0x9C, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05,
|
||||
0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08,
|
||||
0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02,
|
||||
0x00, 0xA0, 0xD6, 0x07, 0xD8, 0x87, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
|
||||
0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2,
|
||||
0x06, 0x08, 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0xE6, 0x07,
|
||||
0xC6, 0x97, 0xF4, 0x94, 0xE6, 0x87, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x1C, 0x88,
|
||||
0x02, 0x01, 0x04, 0xD8, 0x08, 0x97, 0xC6, 0x97, 0xF4, 0x94, 0x0C, 0x88, 0x75, 0x00, 0x00, 0xA3,
|
||||
0x26, 0x08, 0x00, 0x05, 0x10, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
|
||||
0x38, 0x08, 0x00, 0x33, 0x3E, 0x00, 0x82, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63,
|
||||
0x38, 0x2B, 0x5E, 0x88, 0x38, 0x2B, 0x54, 0x88, 0x32, 0x09, 0x31, 0x05, 0x54, 0x98, 0x05, 0x05,
|
||||
0xB2, 0x09, 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32,
|
||||
0x80, 0x36, 0x80, 0x3A, 0x80, 0x3E, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A,
|
||||
0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0x74, 0x08, 0x5D, 0x00, 0xFE, 0xC3,
|
||||
0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
|
||||
0x13, 0x23, 0xB8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01,
|
||||
0x81, 0x62, 0xA2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2,
|
||||
0xF1, 0xC7, 0x41, 0x23, 0xB8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xB2, 0x84,
|
||||
};
|
||||
|
||||
u_int16_t adv_mcode_size = sizeof(adv_mcode);
|
||||
u_int32_t adv_mcode_chksum = 0x012258FB;
|
19
sys/dev/advansys/advmcode.h
Normal file
19
sys/dev/advansys/advmcode.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Exported interface to downloadable microcode for AdvanSys SCSI Adapters
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Obtained from:
|
||||
*
|
||||
* Copyright (c) 1995-1996 Advanced System Products, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that redistributions of source
|
||||
* code retain the above copyright notice and this comment without
|
||||
* modification.
|
||||
*/
|
||||
|
||||
extern u_int16_t adv_mcode[];
|
||||
extern u_int16_t adv_mcode_size;
|
||||
extern u_int32_t adv_mcode_chksum;
|
236
sys/i386/isa/adv_isa.c
Normal file
236
sys/i386/isa/adv_isa.c
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Device probe and attach routines for the following
|
||||
* Advanced Systems Inc. SCSI controllers:
|
||||
*
|
||||
* Connectivity Products:
|
||||
* ABP5140 - Bus-Master PnP ISA 16 CDB
|
||||
*
|
||||
* Single Channel Products:
|
||||
* ABP542 - Bus-Master ISA 240 CDB
|
||||
* ABP5150 - Bus-Master ISA 240 CDB (shipped by HP with the 4020i CD-R drive)
|
||||
* ABP842 - Bus-Master VL 240 CDB
|
||||
*
|
||||
* Dual Channel Products:
|
||||
* ABP852 - Dual Channel Bus-Master VL 240 CDB Per Channel
|
||||
*
|
||||
* Copyright (c) 1996 Justin T. Gibbs.
|
||||
* 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 immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
|
||||
#include <i386/scsi/advansys.h>
|
||||
|
||||
#define ADV_ISA_MAX_DMA_ADDR (0x00FFFFFFL)
|
||||
#define ADV_ISA_MAX_DMA_COUNT (0x00FFFFFFL)
|
||||
|
||||
#define ADV_VL_MAX_DMA_ADDR (0x07FFFFFFL)
|
||||
#define ADV_VL_MAX_DMA_COUNT (0x07FFFFFFL)
|
||||
|
||||
/* Possible port addresses an ISA or VL adapter can live at */
|
||||
u_int16_t adv_isa_ioports[] =
|
||||
{
|
||||
0x100,
|
||||
0x110, /* First selection in BIOS setup */
|
||||
0x120,
|
||||
0x130, /* Second selection in BIOS setup */
|
||||
0x140,
|
||||
0x150, /* Third selection in BIOS setup */
|
||||
0x190, /* Fourth selection in BIOS setup */
|
||||
0x210, /* Fifth selection in BIOS setup */
|
||||
0x230, /* Sixth selection in BIOS setup */
|
||||
0x250, /* Seventh selection in BIOS setup */
|
||||
0x330 /* Eighth and default selection in BIOS setup */
|
||||
};
|
||||
|
||||
#define MAX_ISA_IOPORT_INDEX (sizeof(adv_isa_ioports)/sizeof(u_short) - 1)
|
||||
|
||||
static int advisaprobe __P((struct isa_device *id));
|
||||
static int advisaattach __P((struct isa_device *id));
|
||||
static void adv_set_isapnp_wait_for_key __P((void));
|
||||
static int adv_find_signature __P((u_int16_t iobase));
|
||||
|
||||
void adv_isa_intr __P((int unit));
|
||||
|
||||
struct isa_driver advdriver =
|
||||
{
|
||||
advisaprobe,
|
||||
advisaattach,
|
||||
"adv"
|
||||
};
|
||||
|
||||
static int
|
||||
advisaprobe(id)
|
||||
struct isa_device *id;
|
||||
{
|
||||
int port_index;
|
||||
int max_port_index;
|
||||
|
||||
/*
|
||||
* Default to scanning all possible device locations.
|
||||
*/
|
||||
port_index = 0;
|
||||
max_port_index = MAX_ISA_IOPORT_INDEX;
|
||||
|
||||
if (id->id_iobase > 0) {
|
||||
for (;port_index <= max_port_index; port_index++)
|
||||
if (id->id_iobase >= adv_isa_ioports[port_index])
|
||||
break;
|
||||
if ((port_index > max_port_index)
|
||||
|| (id->id_iobase != adv_isa_ioports[port_index])) {
|
||||
printf("adv%d: Invalid baseport of 0x%x specified. "
|
||||
"Neerest valid baseport is 0x%x. Failing "
|
||||
"probe.\n", id->id_unit, id->id_iobase,
|
||||
(port_index <= max_port_index) ?
|
||||
adv_isa_ioports[port_index] :
|
||||
adv_isa_ioports[max_port_index]);
|
||||
return 0;
|
||||
}
|
||||
max_port_index = port_index;
|
||||
}
|
||||
|
||||
/* Perform the actual probing */
|
||||
adv_set_isapnp_wait_for_key();
|
||||
for (;port_index <= max_port_index; port_index++) {
|
||||
u_int16_t port_addr = adv_isa_ioports[port_index];
|
||||
if (port_addr == 0)
|
||||
/* Already been attached */
|
||||
continue;
|
||||
if (adv_find_signature(port_addr)) {
|
||||
/*
|
||||
* Got one. Now allocate our softc
|
||||
* and see if we can initialize the card.
|
||||
*/
|
||||
struct adv_softc *adv;
|
||||
adv = adv_alloc(id->id_unit, port_addr);
|
||||
if (adv == NULL)
|
||||
return (0);
|
||||
|
||||
id->id_iobase = adv->iobase;
|
||||
/*
|
||||
* Determine the chip version.
|
||||
*/
|
||||
adv->chip_version = ADV_INB(adv,
|
||||
ADV_NONEISA_CHIP_REVISION);
|
||||
|
||||
if (adv_init(adv) != 0) {
|
||||
adv_free(adv);
|
||||
return (0);
|
||||
}
|
||||
switch (adv->type) {
|
||||
case ADV_ISAPNP:
|
||||
if (adv->chip_version == ADV_CHIP_VER_ASYN_BUG)
|
||||
adv->needs_async_bug_fix = TARGET_BIT_VECTOR_SET;
|
||||
/* Fall Through */
|
||||
case ADV_ISA:
|
||||
adv->max_dma_count = ADV_ISA_MAX_DMA_COUNT;
|
||||
break;
|
||||
|
||||
case ADV_VL:
|
||||
adv->max_dma_count = ADV_VL_MAX_DMA_COUNT;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((adv->type & ADV_ISAPNP) == ADV_ISAPNP) {
|
||||
}
|
||||
|
||||
/* Determine our IRQ */
|
||||
if (id->id_irq == 0 /* irq ? */)
|
||||
id->id_irq = 1 << adv_get_chip_irq(adv);
|
||||
else
|
||||
adv_set_chip_irq(adv, ffs(id->id_irq) - 1);
|
||||
|
||||
/* Mark as probed */
|
||||
adv_isa_ioports[port_index] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
advisaattach(id)
|
||||
struct isa_device *id;
|
||||
{
|
||||
struct adv_softc *adv;
|
||||
|
||||
adv = advsoftcs[id->id_unit];
|
||||
return (adv_attach(adv));
|
||||
}
|
||||
|
||||
static void
|
||||
adv_set_isapnp_wait_for_key(void)
|
||||
{
|
||||
static int isapnp_wait_set = 0;
|
||||
if (isapnp_wait_set == 0) {
|
||||
outb(ADV_ISA_PNP_PORT_ADDR, 0x02);
|
||||
outb(ADV_ISA_PNP_PORT_WRITE, 0x02);
|
||||
isapnp_wait_set++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if there is a board at "iobase" by looking
|
||||
* for the AdvanSys signatures. Return 1 if a board is
|
||||
* found, 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
adv_find_signature(iobase)
|
||||
u_int16_t iobase;
|
||||
{
|
||||
u_int16_t signature;
|
||||
|
||||
if (inb(iobase + ADV_SIGNATURE_BYTE) == ADV_1000_ID1B) {
|
||||
signature = inw(iobase + ADV_SIGNATURE_WORD );
|
||||
if ((signature == ADV_1000_ID0W)
|
||||
|| (signature == ADV_1000_ID0W_FIX))
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle an ISA interrupt.
|
||||
* XXX should go away as soon as ISA interrupt handlers
|
||||
* take a (void *) arg.
|
||||
*/
|
||||
void
|
||||
adv_isa_intr(unit)
|
||||
int unit;
|
||||
{
|
||||
struct adv_softc *arg = advsoftcs[unit];
|
||||
adv_intr((void *)arg);
|
||||
}
|
798
sys/i386/scsi/advansys.c
Normal file
798
sys/i386/scsi/advansys.c
Normal file
@ -0,0 +1,798 @@
|
||||
/*
|
||||
* Generic driver for the Advanced Systems Inc. SCSI controllers
|
||||
* Product specific probe and attach routines can be found in:
|
||||
*
|
||||
* i386/isa/adv_isa.c ABP5140, ABP542, ABP5150, ABP842, ABP852
|
||||
*
|
||||
* Copyright (c) 1996 Justin T. Gibbs.
|
||||
* 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 immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
/*
|
||||
* Ported from:
|
||||
* advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
|
||||
*
|
||||
* Copyright (c) 1995-1996 Advanced System Products, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that redistributions of source
|
||||
* code retain the above copyright notice and this comment without
|
||||
* modification.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/buf.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
|
||||
#include <scsi/scsi_all.h>
|
||||
#include <scsi/scsi_message.h>
|
||||
#include <scsi/scsiconf.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <i386/scsi/advansys.h>
|
||||
|
||||
static void adv_scsi_cmd __P((struct scsi_xfer *xs));
|
||||
static void advminphys __P((struct buf *bp));
|
||||
static void * adv_get_cdb __P((void *adapter_softc, struct scsi_queue *sq));
|
||||
static void adv_free_cdb __P((void *adapter_softc, struct scsi_queue *sq,
|
||||
void *cdb));
|
||||
static timeout_t
|
||||
adv_timeout;
|
||||
static int adv_qdone __P((struct adv_softc *adv));
|
||||
static void adv_done __P((struct adv_softc *adv,
|
||||
struct adv_q_done_info *qdonep));
|
||||
static int adv_poll __P((struct adv_softc *ahc, struct scsi_xfer *xs));
|
||||
|
||||
struct adv_softc *advsoftcs[NADV]; /* XXX Config should handle this */
|
||||
|
||||
static struct scsi_adapter adv_switch =
|
||||
{
|
||||
adv_scsi_cmd,
|
||||
advminphys,
|
||||
0,
|
||||
0,
|
||||
adv_get_cdb,
|
||||
adv_free_cdb,
|
||||
"adv"
|
||||
};
|
||||
|
||||
static void
|
||||
adv_scsi_cmd(xs)
|
||||
struct scsi_xfer *xs;
|
||||
{
|
||||
struct adv_softc *adv;
|
||||
struct adv_scsi_q scsiq;
|
||||
struct adv_sg_head sghead;
|
||||
|
||||
SC_DEBUG(xs->sc_link, SDEV_DB2, ("adv_scsi_cmd\n"));
|
||||
|
||||
adv = (struct adv_softc *)xs->sc_link->scsibus->adpt_link.adpt_softc;
|
||||
|
||||
/*
|
||||
* Build up the request
|
||||
*/
|
||||
scsiq.q1.cntl = 0;
|
||||
scsiq.q1.sg_queue_cnt = 0;
|
||||
scsiq.q1.status = 0;
|
||||
scsiq.q1.q_no = 0;
|
||||
scsiq.q1.target_id = ADV_TID_TO_TARGET_ID(xs->sc_link->target);
|
||||
scsiq.q1.target_lun = xs->sc_link->lun;
|
||||
scsiq.q1.sense_addr = (u_int32_t)vtophys(&xs->sense);
|
||||
scsiq.q1.sense_len = sizeof(xs->sense);
|
||||
scsiq.q1.data_cnt = 0;
|
||||
scsiq.q1.data_addr = 0;
|
||||
scsiq.q1.user_def = 0;
|
||||
scsiq.q2.xs_ptr = (u_int32_t)xs;
|
||||
scsiq.q2.target_ix = ADV_TIDLUN_TO_IX(xs->sc_link->target, xs->sc_link->lun);
|
||||
scsiq.q2.flag = 0;
|
||||
scsiq.q2.cdb_len = xs->cmdlen;
|
||||
scsiq.q2.tag_code = xs->tag_type;
|
||||
scsiq.q2.vm_id = 0;
|
||||
scsiq.sg_head = NULL;
|
||||
scsiq.cdbptr = &xs->cmdstore;
|
||||
|
||||
if (xs->datalen) {
|
||||
/*
|
||||
* Determin the number of segments needed for this
|
||||
* transfer. We should only use SG if we need more
|
||||
* than one.
|
||||
*/
|
||||
int seg;
|
||||
u_int32_t datalen;
|
||||
vm_offset_t vaddr;
|
||||
u_int32_t paddr;
|
||||
u_int32_t nextpaddr;
|
||||
struct adv_sg_entry *sg;
|
||||
|
||||
seg = 0;
|
||||
datalen = xs->datalen;
|
||||
vaddr = (vm_offset_t)xs->data;
|
||||
paddr = vtophys(vaddr);
|
||||
sg = &sghead.sg_list[0];
|
||||
|
||||
while ((datalen > 0) && (seg < ADV_MAX_SG_LIST)) {
|
||||
/* put in the base address and length */
|
||||
sg->addr = paddr;
|
||||
sg->bytes = 0;
|
||||
|
||||
/* do it at least once */
|
||||
nextpaddr = paddr;
|
||||
|
||||
while ((datalen > 0) && (paddr == nextpaddr)) {
|
||||
u_int32_t size;
|
||||
/*
|
||||
* This page is contiguous (physically)
|
||||
* with the the last, just extend the
|
||||
* length
|
||||
*/
|
||||
/* how far to the end of the page */
|
||||
nextpaddr = (paddr & (~PAGE_MASK)) + PAGE_SIZE;
|
||||
|
||||
/*
|
||||
* Compute the maximum size
|
||||
*/
|
||||
size = nextpaddr - paddr;
|
||||
if (size > datalen)
|
||||
size = datalen;
|
||||
|
||||
sg->bytes += size;
|
||||
vaddr += size;
|
||||
datalen -= size;
|
||||
if (datalen > 0)
|
||||
paddr = vtophys(vaddr);
|
||||
}
|
||||
/*
|
||||
* next page isn't contiguous, finish the seg
|
||||
*/
|
||||
seg++;
|
||||
sg++;
|
||||
}
|
||||
if (seg > 1) {
|
||||
scsiq.q1.cntl |= QC_SG_HEAD;
|
||||
scsiq.sg_head = &sghead;
|
||||
sghead.entry_cnt = sghead.entry_to_copy = seg;
|
||||
sghead.res = 0;
|
||||
}
|
||||
scsiq.q1.data_addr = sghead.sg_list[0].addr;
|
||||
scsiq.q1.data_cnt = sghead.sg_list[0].bytes;
|
||||
}
|
||||
|
||||
if (adv_execute_scsi_queue(adv, &scsiq) != 0) {
|
||||
/* XXX Add freeze queue functionality */
|
||||
xs->error = XS_BUSY;
|
||||
scsi_done(xs);
|
||||
DELAY(20 * 1000 * 1000);
|
||||
} else if ((xs->flags & SCSI_POLL) != 0) {
|
||||
/*
|
||||
* If we can't use interrupts, poll for completion
|
||||
*/
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
if (adv_poll(adv, xs)) {
|
||||
if (!(xs->flags & SCSI_SILENT))
|
||||
printf("cmd fail\n");
|
||||
adv_timeout(xs);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
advminphys(bp)
|
||||
struct buf *bp;
|
||||
{
|
||||
if (bp->b_bcount > ((ADV_MAX_SG_LIST - 1) * PAGE_SIZE))
|
||||
bp->b_bcount = ((ADV_MAX_SG_LIST - 1) * PAGE_SIZE);
|
||||
}
|
||||
|
||||
static void *
|
||||
adv_get_cdb(adapter_softc, sq)
|
||||
void *adapter_softc;
|
||||
struct scsi_queue *sq;
|
||||
{
|
||||
return ((void *)1);
|
||||
}
|
||||
|
||||
static void
|
||||
adv_free_cdb(adapter_softc, sq, cdb)
|
||||
void *adapter_softc;
|
||||
struct scsi_queue *sq;
|
||||
void *cdb;
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
adv_timeout(arg)
|
||||
void *arg;
|
||||
{
|
||||
printf("adv: Ooops. Had a timeout\n");
|
||||
}
|
||||
|
||||
struct adv_softc *
|
||||
adv_alloc(unit, iobase)
|
||||
int unit;
|
||||
u_long iobase;
|
||||
{
|
||||
struct adv_softc *adv;
|
||||
int i;
|
||||
|
||||
if (unit >= NADV) {
|
||||
printf("adv: unit number (%d) too high\n", unit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a storage area for us
|
||||
*/
|
||||
if (advsoftcs[unit]) {
|
||||
printf("adv%d: memory already allocated\n", unit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
adv = malloc(sizeof(struct adv_softc), M_DEVBUF, M_NOWAIT);
|
||||
if (!adv) {
|
||||
printf("adv%d: cannot malloc!\n", unit);
|
||||
return NULL;
|
||||
}
|
||||
bzero(adv, sizeof(struct adv_softc));
|
||||
advsoftcs[unit] = adv;
|
||||
adv->unit = unit;
|
||||
adv->iobase = iobase;
|
||||
|
||||
/* Set reasonable defaults incase we can't read the EEPROM */
|
||||
adv->max_openings = ADV_DEF_MAX_TOTAL_QNG;
|
||||
adv->start_motor = TARGET_BIT_VECTOR_SET;
|
||||
adv->disc_enable = TARGET_BIT_VECTOR_SET;
|
||||
adv->cmd_qng_enabled = TARGET_BIT_VECTOR_SET;
|
||||
adv->scsi_id = 7;
|
||||
|
||||
for (i = 0; i <= ADV_MAX_TID; i++)
|
||||
adv->sdtr_data[i] = ADV_DEF_SDTR_OFFSET | (ADV_DEF_SDTR_INDEX << 4);
|
||||
|
||||
return(adv);
|
||||
}
|
||||
|
||||
void
|
||||
adv_free(adv)
|
||||
struct adv_softc *adv;
|
||||
{
|
||||
if (adv->sense_buffers != NULL)
|
||||
free(adv->sense_buffers, M_DEVBUF);
|
||||
free(adv, M_DEVBUF);
|
||||
}
|
||||
|
||||
int
|
||||
adv_init(adv)
|
||||
struct adv_softc *adv;
|
||||
{
|
||||
struct adv_eeprom_config eeprom_config;
|
||||
int checksum, i;
|
||||
u_int16_t config_lsw;
|
||||
u_int16_t config_msw;
|
||||
|
||||
adv_get_board_type(adv);
|
||||
|
||||
/*
|
||||
* Stop script execution.
|
||||
*/
|
||||
adv_write_lram_16(adv, ADV_HALTCODE_W, 0x00FE);
|
||||
adv_stop_execution(adv);
|
||||
adv_reset_chip_and_scsi_bus(adv);
|
||||
/*
|
||||
* The generic SCSI code does a minimum delay for us
|
||||
* already.
|
||||
*/
|
||||
/* DELAY(3 * 1000 * 1000);*/ /* 3 Second Delay */
|
||||
if (adv_is_chip_halted(adv) == 0) {
|
||||
printf("adv%d: Unable to halt adapter. Initialization"
|
||||
"failed\n", adv->unit);
|
||||
return (1);
|
||||
}
|
||||
ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR);
|
||||
if (ADV_INW(adv, ADV_REG_PROG_COUNTER) != ADV_MCODE_START_ADDR) {
|
||||
printf("adv%d: Unable to set program counter. Initialization"
|
||||
"failed\n", adv->unit);
|
||||
return (1);
|
||||
}
|
||||
|
||||
config_lsw = ADV_INW(adv, ADV_CONFIG_LSW);
|
||||
config_msw = ADV_INW(adv, ADV_CONFIG_MSW);
|
||||
|
||||
#if 0
|
||||
/* XXX Move to PCI probe code */
|
||||
if (adv->type & ADV_PCI) {
|
||||
#if CC_DISABLE_PCI_PARITY_INT
|
||||
config_msw &= 0xFFC0;
|
||||
ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw);
|
||||
#endif
|
||||
|
||||
if (asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_A) {
|
||||
asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ADD_ONE_BYTE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if ((config_msw & ADV_CFG_MSW_CLR_MASK) != 0) {
|
||||
config_msw &= (~(ADV_CFG_MSW_CLR_MASK));
|
||||
/*
|
||||
* XXX The Linux code flags this as an error,
|
||||
* but what should we report to the user???
|
||||
* It seems that clearing the config register
|
||||
* makes this error recoverable.
|
||||
*/
|
||||
ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw);
|
||||
}
|
||||
|
||||
/* Suck in the configuration from the EEProm */
|
||||
checksum = adv_get_eeprom_config(adv, &eeprom_config);
|
||||
|
||||
eeprom_config.cfg_msw &= (~(ADV_CFG_MSW_CLR_MASK));
|
||||
|
||||
if (ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_AUTO_CONFIG) {
|
||||
/*
|
||||
* XXX The Linux code sets a warning level for this
|
||||
* condition, yet nothing of meaning is printed to
|
||||
* the user. What does this mean???
|
||||
*/
|
||||
if (adv->chip_version == 3) {
|
||||
if (eeprom_config.cfg_lsw != config_lsw) {
|
||||
/* XXX Yet another supposed Warning */
|
||||
eeprom_config.cfg_lsw =
|
||||
ADV_INW(adv, ADV_CONFIG_LSW);
|
||||
}
|
||||
if (eeprom_config.cfg_msw != config_msw) {
|
||||
/* XXX Yet another supposed Warning */
|
||||
eeprom_config.cfg_msw =
|
||||
ADV_INW(adv, ADV_CONFIG_MSW);
|
||||
}
|
||||
}
|
||||
}
|
||||
eeprom_config.cfg_lsw |= ADV_CFG_LSW_HOST_INT_ON;
|
||||
if (checksum == eeprom_config.chksum) {
|
||||
if (adv_test_external_lram(adv) == 0) {
|
||||
if (adv->type & ADV_PCI) {
|
||||
eeprom_config.cfg_msw |= 0x0800;
|
||||
config_msw |= 0x0800;
|
||||
ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw);
|
||||
eeprom_config.max_total_qng = ADV_MAX_PCI_INRAM_TOTAL_QNG;
|
||||
eeprom_config.max_tag_qng = ADV_MAX_INRAM_TAG_QNG;
|
||||
}
|
||||
}
|
||||
/* XXX What about wide bussed cards?? */
|
||||
for (i = 0; i <= 7; i++)
|
||||
adv->sdtr_data[i] = eeprom_config.sdtr_data[i];
|
||||
|
||||
/* Range/Sanity checking */
|
||||
if (eeprom_config.max_total_qng < ADV_MIN_TOTAL_QNG) {
|
||||
eeprom_config.max_total_qng = ADV_MIN_TOTAL_QNG;
|
||||
}
|
||||
if (eeprom_config.max_total_qng > ADV_MAX_TOTAL_QNG) {
|
||||
eeprom_config.max_total_qng = ADV_MAX_TOTAL_QNG;
|
||||
}
|
||||
if (eeprom_config.max_tag_qng > eeprom_config.max_total_qng) {
|
||||
eeprom_config.max_tag_qng = eeprom_config.max_total_qng;
|
||||
}
|
||||
if (eeprom_config.max_tag_qng < ADV_MIN_TAG_Q_PER_DVC) {
|
||||
eeprom_config.max_tag_qng = ADV_MIN_TAG_Q_PER_DVC;
|
||||
}
|
||||
adv->max_openings = eeprom_config.max_total_qng;
|
||||
|
||||
if ((eeprom_config.use_cmd_qng & eeprom_config.disc_enable) !=
|
||||
eeprom_config.use_cmd_qng) {
|
||||
eeprom_config.disc_enable |= eeprom_config.use_cmd_qng;
|
||||
printf("adv:%d: WARNING! One or more targets with tagged "
|
||||
"queuing enabled have the disconnection priveledge "
|
||||
"disabled.\n"
|
||||
"adv:%d: Overriding disconnection settings to "
|
||||
"allow tagged queueing devices to disconnect.\n ",
|
||||
adv->unit, adv->unit);
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* XXX We should range check our target ID
|
||||
* based on the width of our bus
|
||||
*/
|
||||
EEPROM_SET_SCSIID(eeprom_config,
|
||||
EEPROM_SCSIID(eeprom_config) & ADV_MAX_TID);
|
||||
#endif
|
||||
adv->initiate_sdtr = eeprom_config.init_sdtr;
|
||||
adv->disc_enable = eeprom_config.disc_enable;
|
||||
adv->cmd_qng_enabled = eeprom_config.use_cmd_qng;
|
||||
adv->isa_dma_speed = EEPROM_DMA_SPEED(eeprom_config);
|
||||
adv->scsi_id = EEPROM_SCSIID(eeprom_config);
|
||||
adv->start_motor = eeprom_config.start_motor;
|
||||
adv->control = eeprom_config.cntl;
|
||||
adv->no_scam = eeprom_config.no_scam;
|
||||
} else {
|
||||
/*
|
||||
* Use the defaults that adv was initialized with.
|
||||
*/
|
||||
/*
|
||||
* XXX Fixup EEPROM with default values???
|
||||
*/
|
||||
printf("adv%d: Warning EEPROM Checksum mismatch. "
|
||||
"Using default device parameters\n", adv->unit);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX Do this in the PCI probe */
|
||||
if ((adv->btype & ADV_PCI) &&
|
||||
!(asc_dvc->dvc_cntl & ASC_CNTL_NO_PCI_FIX_ASYN_XFER)) {
|
||||
if ((asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
|
||||
(asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
|
||||
asc_dvc->pci_fix_asyn_xfer = ASC_ALL_DEVICE_BIT_SET;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (adv_set_eeprom_config(adv, &eeprom_config) != 0)
|
||||
printf("adv:%d: WARNING! Failure writing to EEPROM.\n");
|
||||
|
||||
/* Allocate space for our sense buffers */
|
||||
/* XXX this should really be done by the generic SCSI layer by ensuring
|
||||
* that all scsi_xfer structs are allocated below 16M if any controller
|
||||
* needs to bounce.
|
||||
*/
|
||||
if (adv->type & ADV_ISA) {
|
||||
adv->sense_buffers = (struct scsi_sense_data *)contigmalloc(sizeof(struct scsi_sense_data) * adv->max_openings,
|
||||
M_DEVBUF, M_NOWAIT, 0ul, 0xfffffful, 1ul,
|
||||
0x10000ul);
|
||||
if (adv->sense_buffers == NULL) {
|
||||
printf("adv%d: Unable to allocate sense buffer space.\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (adv_init_lram_and_mcode(adv))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
adv_intr(arg)
|
||||
void *arg;
|
||||
{
|
||||
struct adv_softc *adv;
|
||||
u_int16_t chipstat;
|
||||
u_int16_t saved_ram_addr;
|
||||
u_int8_t ctrl_reg;
|
||||
u_int8_t saved_ctrl_reg;
|
||||
int status;
|
||||
u_int8_t host_flag;
|
||||
|
||||
adv = (struct adv_softc *)arg;
|
||||
|
||||
ctrl_reg = ADV_INB(adv, ADV_CHIP_CTRL);
|
||||
saved_ctrl_reg = ctrl_reg & (~(ADV_CC_SCSI_RESET | ADV_CC_CHIP_RESET |
|
||||
ADV_CC_SINGLE_STEP | ADV_CC_DIAG | ADV_CC_TEST));
|
||||
|
||||
|
||||
if ((chipstat = ADV_INW(adv, ADV_CHIP_STATUS)) & ADV_CSW_INT_PENDING) {
|
||||
|
||||
adv_ack_interrupt(adv);
|
||||
|
||||
host_flag = adv_read_lram_8(adv, ADVV_HOST_FLAG_B);
|
||||
adv_write_lram_8(adv, ADVV_HOST_FLAG_B,
|
||||
host_flag | ADV_HOST_FLAG_IN_ISR);
|
||||
saved_ram_addr = ADV_INW(adv, ADV_LRAM_ADDR);
|
||||
|
||||
if ((chipstat & ADV_CSW_HALTED)
|
||||
&& (ctrl_reg & ADV_CC_SINGLE_STEP)) {
|
||||
adv_isr_chip_halted(adv);
|
||||
saved_ctrl_reg &= ~ADV_CC_HALT;
|
||||
} else {
|
||||
if ((adv->control & ADV_CNTL_INT_MULTI_Q) != 0) {
|
||||
while (((status = adv_qdone(adv)) & 0x01) != 0)
|
||||
;
|
||||
} else {
|
||||
do {
|
||||
status = adv_qdone(adv);
|
||||
} while (status == 0x11);
|
||||
}
|
||||
}
|
||||
ADV_OUTW(adv, ADV_LRAM_ADDR, saved_ram_addr);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (ADV_INW(adv, ADV_LRAM_ADDR) != saved_ram_addr)
|
||||
panic("adv_intr: Unable to set LRAM addr");
|
||||
#endif
|
||||
adv_write_lram_8(adv, ADVV_HOST_FLAG_B, host_flag);
|
||||
}
|
||||
|
||||
ADV_OUTB(adv, ADV_CHIP_CTRL, saved_ctrl_reg);
|
||||
}
|
||||
|
||||
int
|
||||
adv_qdone(adv)
|
||||
struct adv_softc *adv;
|
||||
{
|
||||
u_int8_t next_qp;
|
||||
u_int8_t i;
|
||||
u_int8_t n_q_used;
|
||||
u_int8_t sg_list_qp;
|
||||
u_int8_t sg_queue_cnt;
|
||||
u_int8_t done_q_tail;
|
||||
u_int8_t tid_no;
|
||||
target_bit_vector target_id;
|
||||
u_int16_t q_addr;
|
||||
u_int16_t sg_q_addr;
|
||||
struct adv_q_done_info scsiq_buf;
|
||||
struct adv_q_done_info *scsiq;
|
||||
int false_overrun;
|
||||
u_int8_t tag_code;
|
||||
|
||||
n_q_used = 1;
|
||||
scsiq = &scsiq_buf;
|
||||
done_q_tail = adv_read_lram_16(adv, ADVV_DONE_Q_TAIL_W) & 0xFF;
|
||||
q_addr = ADV_QNO_TO_QADDR(done_q_tail);
|
||||
next_qp = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_FWD);
|
||||
if (next_qp != ADV_QLINK_END) {
|
||||
adv_write_lram_16(adv, ADVV_DONE_Q_TAIL_W, next_qp);
|
||||
q_addr = ADV_QNO_TO_QADDR(next_qp);
|
||||
|
||||
sg_queue_cnt = adv_copy_lram_doneq(adv, q_addr, scsiq, adv->max_dma_count);
|
||||
|
||||
adv_write_lram_8(adv, q_addr + ADV_SCSIQ_B_STATUS,
|
||||
scsiq->q_status & ~(QS_READY | QS_ABORTED));
|
||||
tid_no = ADV_TIX_TO_TID(scsiq->d2.target_ix);
|
||||
target_id = ADV_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
|
||||
if ((scsiq->cntl & QC_SG_HEAD) != 0) {
|
||||
sg_q_addr = q_addr;
|
||||
sg_list_qp = next_qp;
|
||||
for (i = 0; i < sg_queue_cnt; i++) {
|
||||
sg_list_qp = adv_read_lram_8(adv,
|
||||
sg_q_addr + ADV_SCSIQ_B_FWD);
|
||||
sg_q_addr = ADV_QNO_TO_QADDR(sg_list_qp);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (sg_list_qp == ASC_QLINK_END) {
|
||||
panic("adv_qdone: Corrupted SG list encountered");
|
||||
}
|
||||
#endif
|
||||
adv_write_lram_8(adv, sg_q_addr + ADV_SCSIQ_B_STATUS,
|
||||
QS_FREE);
|
||||
}
|
||||
|
||||
n_q_used = sg_queue_cnt + 1;
|
||||
adv_write_lram_16(adv, ADVV_DONE_Q_TAIL_W, sg_list_qp);
|
||||
}
|
||||
#if 0
|
||||
/* XXX Fix later */
|
||||
if (adv->queue_full_or_busy & target_id) {
|
||||
cur_target_qng = adv_read_lram_8(adv,
|
||||
ADV_QADR_BEG + scsiq->d2.target_ix);
|
||||
if (cur_target_qng < adv->max_dvc_qng[tid_no]) {
|
||||
scsi_busy = adv_read_lram_8(adv, ADVV_SCSIBUSY_B);
|
||||
scsi_busy &= ~target_id;
|
||||
adv_write_lram_8(adv, ADVV_SCSIBUSY_B, scsi_busy);
|
||||
adv->queue_full_or_busy &= ~target_id;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef DIAGNOSTIC
|
||||
if (adv->cur_total_qng < n_q_used)
|
||||
panic("adv_qdone: Attempting to free more queues than are active");
|
||||
#endif
|
||||
adv->cur_active -= n_q_used;
|
||||
|
||||
if ((scsiq->d2.xs_ptr == 0) ||
|
||||
((scsiq->q_status & QS_ABORTED) != 0))
|
||||
return (0x11);
|
||||
else if (scsiq->q_status == QS_DONE) {
|
||||
|
||||
false_overrun = FALSE;
|
||||
|
||||
if (adv->bug_fix_control & ADV_BUG_FIX_ADD_ONE_BYTE) {
|
||||
tag_code = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_TAG_CODE);
|
||||
if (tag_code & ADV_TAG_FLAG_ADD_ONE_BYTE) {
|
||||
if (scsiq->remain_bytes != 0) {
|
||||
scsiq->remain_bytes--;
|
||||
if (scsiq->remain_bytes == 0)
|
||||
false_overrun = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((scsiq->d3.done_stat == QD_WITH_ERROR) &&
|
||||
(scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN)) {
|
||||
if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
|
||||
scsiq->d3.done_stat = QD_NO_ERROR;
|
||||
scsiq->d3.host_stat = QHSTA_NO_ERROR;
|
||||
} else if (false_overrun) {
|
||||
scsiq->d3.done_stat = QD_NO_ERROR;
|
||||
scsiq->d3.host_stat = QHSTA_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if ((scsiq->cntl & QC_NO_CALLBACK) == 0)
|
||||
adv_done(adv, scsiq);
|
||||
else {
|
||||
if ((adv_read_lram_8(adv, q_addr + ADV_SCSIQ_CDB_BEG) ==
|
||||
START_STOP)) {
|
||||
adv->unit_not_ready &= ~target_id;
|
||||
if (scsiq->d3.done_stat != QD_NO_ERROR)
|
||||
adv->start_motor &= ~target_id;
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
} else {
|
||||
panic("adv_qdone: completed scsiq with unknown status");
|
||||
#if 0
|
||||
/*
|
||||
* XXX Doesn't this simply indicate a software bug?
|
||||
* What does setting the lram error code do for
|
||||
* you. Would we even recover?
|
||||
*/
|
||||
AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
|
||||
|
||||
FATAL_ERR_QDONE:
|
||||
if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
|
||||
(*asc_isr_callback) (asc_dvc, scsiq);
|
||||
}
|
||||
return (0x80);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
adv_done(adv, qdonep)
|
||||
struct adv_softc *adv;
|
||||
struct adv_q_done_info *qdonep;
|
||||
{
|
||||
struct scsi_xfer *xs;
|
||||
|
||||
xs = (struct scsi_xfer *)qdonep->d2.xs_ptr;
|
||||
|
||||
xs->status = qdonep->d3.scsi_stat;
|
||||
/*
|
||||
* 'qdonep' contains the command's ending status.
|
||||
*/
|
||||
switch (qdonep->d3.done_stat) {
|
||||
case QD_NO_ERROR:
|
||||
switch (qdonep->d3.host_stat) {
|
||||
case QHSTA_NO_ERROR:
|
||||
break;
|
||||
case QHSTA_M_SEL_TIMEOUT:
|
||||
xs->error = XS_SELTIMEOUT;
|
||||
break;
|
||||
default:
|
||||
/* QHSTA error occurred */
|
||||
/* XXX Can I get more explicit information here? */
|
||||
xs->error = XS_DRIVER_STUFFUP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case QD_WITH_ERROR:
|
||||
switch (qdonep->d3.host_stat) {
|
||||
case QHSTA_NO_ERROR:
|
||||
if (qdonep->d3.scsi_stat == SCSI_CHECK) {
|
||||
/* We have valid sense information to return */
|
||||
xs->error = XS_SENSE;
|
||||
if (adv->sense_buffers != NULL)
|
||||
/* Structure copy */
|
||||
xs->sense = adv->sense_buffers[qdonep->q_no];
|
||||
}
|
||||
break;
|
||||
case QHSTA_M_SEL_TIMEOUT:
|
||||
xs->error = XS_SELTIMEOUT;
|
||||
break;
|
||||
default:
|
||||
/* XXX Can I get more explicit information here? */
|
||||
xs->error = XS_DRIVER_STUFFUP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case QD_ABORTED_BY_HOST:
|
||||
/* XXX Should have an explicit ABORTED error code */
|
||||
xs->error = XS_DRIVER_STUFFUP;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("adv_done: Unknown done status 0x%x\n", qdonep->d3.done_stat);
|
||||
xs->error = XS_DRIVER_STUFFUP;
|
||||
break;
|
||||
}
|
||||
xs->flags |= ITSDONE;
|
||||
scsi_done(xs);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to poll for command completion when
|
||||
* interrupts are disabled (crash dumps)
|
||||
*/
|
||||
static int
|
||||
adv_poll(adv, xs)
|
||||
struct adv_softc *adv;
|
||||
struct scsi_xfer *xs;
|
||||
{
|
||||
int wait;
|
||||
|
||||
wait = xs->timeout;
|
||||
do {
|
||||
DELAY(1000);
|
||||
adv_intr((void *)adv);
|
||||
} while (--wait && ((xs->flags & ITSDONE) == 0));
|
||||
if (wait == 0) {
|
||||
printf("adv%d: board is not responding\n", adv->unit);
|
||||
return (EIO);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach all the sub-devices we can find
|
||||
*/
|
||||
int
|
||||
adv_attach(adv)
|
||||
struct adv_softc *adv;
|
||||
{
|
||||
struct scsi_bus *scbus;
|
||||
struct scsi_queue *scsiq;
|
||||
|
||||
scsiq = scsi_alloc_queue(adv->max_openings);
|
||||
if (scsiq == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Prepare the scsi_bus area for the upperlevel scsi code.
|
||||
*/
|
||||
scbus = scsi_alloc_bus(&adv_switch, adv, adv->unit, scsiq);
|
||||
if (scbus == NULL) {
|
||||
scsi_free_queue(scsiq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Override defaults */
|
||||
if ((adv->type & ADV_ISA) != 0)
|
||||
scbus->adpt_link.adpt_flags |= SADPT_BOUNCE;
|
||||
scbus->adpt_link.adpt_target = adv->scsi_id;
|
||||
scbus->adpt_link.adpt_openings = 2; /* XXX Is this correct for these cards? */
|
||||
scbus->adpt_link.adpt_tagged_openings = adv->max_openings;
|
||||
|
||||
/*
|
||||
* ask the adapter what subunits are present
|
||||
*/
|
||||
if(bootverbose)
|
||||
printf("adv%d: Probing SCSI bus\n", adv->unit);
|
||||
|
||||
scsi_attachdevs(scbus);
|
||||
|
||||
return 1;
|
||||
}
|
50
sys/i386/scsi/advansys.h
Normal file
50
sys/i386/scsi/advansys.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Generic driver for the Advanced Systems Inc. SCSI controllers
|
||||
* Product specific probe and attach routines can be found in:
|
||||
*
|
||||
* XXX Fill this in.
|
||||
*
|
||||
* Copyright (c) 1996 Justin T. Gibbs.
|
||||
* 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 immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _ADVANSYS_H_
|
||||
#define _ADVANSYS_H_
|
||||
|
||||
#include "adv.h"
|
||||
#include <dev/advansys/advlib.h>
|
||||
|
||||
struct adv_softc * adv_alloc __P((int unit, u_long iobase));
|
||||
void adv_free __P((struct adv_softc *adv));
|
||||
int adv_init __P((struct adv_softc *adv));
|
||||
void adv_intr __P((void *arg));
|
||||
int adv_attach __P((struct adv_softc *adv));
|
||||
|
||||
extern struct adv_softc *advsoftcs[NADV]; /* XXX Config should handle this */
|
||||
#endif /* _ADVANSYS_H_ */
|
Loading…
Reference in New Issue
Block a user