diff options
Diffstat (limited to 'sys/dev/aha/ahareg.h')
-rw-r--r-- | sys/dev/aha/ahareg.h | 464 |
1 files changed, 464 insertions, 0 deletions
diff --git a/sys/dev/aha/ahareg.h b/sys/dev/aha/ahareg.h new file mode 100644 index 0000000..30c9b7a --- /dev/null +++ b/sys/dev/aha/ahareg.h @@ -0,0 +1,464 @@ +/* + * Generic register and struct definitions for the Adaptech 154x/164x + * SCSI host adapters. Product specific probe and attach routines can + * be found in: + * <fill in list here> + * + * Derived from bt.c written by: + * + * Copyright (c) 1998 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, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. 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 _AHAREG_H_ +#define _AHAREG_H_ + +#include "aha.h" + +#include <sys/queue.h> +#include <cam/scsi/scsi_all.h> + +#define AHA_MAXTRANSFER_SIZE 0xffffff /* limited by 24bit counter */ +#define AHA_NSEG 17 /* The number of dma segments + * supported. */ +#define ALL_TARGETS (~0) + +/* + * Control Register pp. 1-8, 1-9 (Write Only) + */ +#define CONTROL_REG 0x00 +#define HARD_RESET 0x80 /* Hard Reset - return to POST state */ +#define SOFT_RESET 0x40 /* Soft Reset - Clears Adapter state */ +#define RESET_INTR 0x20 /* Reset/Ack Interrupt */ +#define RESET_SBUS 0x10 /* Drive SCSI bus reset signal */ + +/* + * Status Register pp. 1-9, 1-10 (Read Only) + */ +#define STATUS_REG 0x00 +#define DIAG_ACTIVE 0x80 /* Performing Internal Diags */ +#define DIAG_FAIL 0x40 /* Internal Diags failed */ +#define INIT_REQUIRED 0x20 /* MBOXes need initialization */ +#define HA_READY 0x10 /* HA ready for new commands */ +#define CMD_REG_BUSY 0x08 /* HA busy with last cmd byte */ +#define DATAIN_REG_READY 0x04 /* Data-in Byte available */ +#define STATUS_REG_RSVD 0x02 +#define CMD_INVALID 0x01 /* Invalid Command detected */ + +/* + * Command/Parameter Register pp. 1-10, 1-11 (Write Only) + */ +#define COMMAND_REG 0x01 + +/* + * Data in Register p. 1-11 (Read Only) + */ +#define DATAIN_REG 0x01 + +/* + * Interrupt Status Register pp. 1-12 -> 1-14 (Read Only) + */ +#define INTSTAT_REG 0x02 +#define INTR_PENDING 0x80 /* There is a pending INTR */ +#define INTSTAT_REG_RSVD 0x70 +#define SCSI_BUS_RESET 0x08 /* Bus Reset detected */ +#define CMD_COMPLETE 0x04 +#define OMB_READY 0x02 /* Outgoin Mailbox Ready */ +#define IMB_LOADED 0x01 /* Incoming Mailbox loaded */ + +/* + * Definitions for the "undocumented" geometry register + */ +typedef enum { + GEOM_NODISK, + GEOM_64x32, + GEOM_128x32, + GEOM_255x32 +} disk_geom_t; + +#define GEOMETRY_REG 0x03 +#define DISK0_GEOMETRY 0x03 +#define DISK1_GEOMETRY 0x0c +#define EXTENDED_TRANSLATION 0x10 +#define GEOMETRY_DISK0(g_reg) (greg & DISK0_GEOMETRY) +#define GEOMETRY_DISK1(g_reg) ((greg & DISK1_GEOMETRY) >> 2) + +#define AHA_NREGS (4) + +/* + * Opcodes for Adapter commands. + */ +typedef enum { + BOP_NOP = 0x00, + BOP_INITIALIZE_MBOX = 0x01, + BOP_START_MBOX = 0x02, + BOP_EXECUTE_BIOS_CMD = 0x03, + BOP_INQUIRE_BOARD_ID = 0x04, + BOP_ENABLE_OMBR_INT = 0x05, + BOP_SET_SEL_TIMOUT = 0x06, + BOP_SET_TIME_ON_BUS = 0x07, + BOP_SET_TIME_OFF_BUS = 0x08, + BOP_SET_BUS_TRANS_RATE = 0x09, + BOP_INQUIRE_INST_LDEVS = 0x0A, + BOP_INQUIRE_CONFIG = 0x0B, + BOP_ENABLE_TARGET_MODE = 0x0C, + BOP_INQUIRE_SETUP_INFO = 0x0D, + BOP_WRITE_LRAM = 0x1A, + BOP_READ_LRAM = 0x1B, + BOP_WRITE_CHIP_FIFO = 0x1C, + BOP_READ_CHIP_FIFO = 0x1D, + BOP_ECHO_DATA_BYTE = 0x1F, + BOP_ADAPTER_DIAGNOSTICS = 0x20, + BOP_SET_ADAPTER_OPTIONS = 0x21, + BOP_SET_EEPROM = 0x22, + BOP_RETURN_EEPROM = 0x23, + BOP_ENABLE_SHADOW_RAM = 0x24, + BOP_INIT_BIOS_MBOX = 0x25, + BOP_SET_BIOS_BANK_1 = 0x26, + BOP_SET_BIOS_BANK_2 = 0x27, + BOP_RETURN_EXT_BIOS_INFO= 0x28, + BOP_MBOX_IF_ENABLE = 0x29, + BOP_SCSI_TERM_STATUS = 0x2C, + BOP_INQUIRE_SCAM_DEV = 0x2D, + BOP_SCSI_DEV_TABLE = 0x2E, + BOP_SCAM_OP = 0x2F, + BOP_START_BIOS_CMD = 0x82, + BOP_INQUIRE_ESETUP_INFO = 0x8D +} aha_op_t; + +/************** Definitions of Multi-byte commands and responses ************/ + +struct aha_extbios +{ + u_int8_t flags; /* Bit 3 == 1 extended bios enabled */ + u_int8_t mailboxlock; /* mail box lock code to unlock it */ +}; + +/* This is really a bustech command, but we use it to differentiate between */ +/* the aha and bt */ +typedef struct { + u_int8_t bus_type; + u_int8_t bios_addr; + u_int16_t max_sg; + u_int8_t num_mboxes; + u_int8_t mbox_base[4]; + u_int8_t :2, + sync_neg10MB :1, + floppy_disable :1, + floppy_secondary_port :1, + burst_mode_enabled :1, + level_trigger_ints :1, + :1; + u_int8_t fw_ver_bytes_2_to_4[3]; + u_int8_t wide_bus :1, + diff_bus :1, + scam_capable :1, + ultra_scsi :1, + auto_term :1, + :3; +} esetup_info_data_t; + +typedef struct { + u_int8_t num_mboxes; + u_int8_t base_addr[3]; +} init_24b_mbox_params_t; + +typedef struct { + u_int8_t board_type; +/* These values are mostly from the aha-1540CP technical reference, but */ +/* with other values from the old aha1542.c driver. */ +#define BOARD_1540_16HEAD_BIOS 0x00 +#define BOARD_1540_64HEAD_BIOS 0x30 +#define BOARD_1542 0x41 /* aha-1540/1542 w/64-h bios */ +#define BOARD_1640 0x42 /* aha-1640 */ +#define BOARD_1740 0x43 /* aha-1740A/1742A/1744 */ +#define BOARD_1542C 0x44 /* aha-1542C */ +#define BOARD_1542CF 0x45 /* aha-1542CF */ +#define BOARD_1542CP 0x46 /* aha-1542CP, plug and play */ + u_int8_t cust_features; +#define FEATURES_STANDARD 0x30 + u_int8_t firmware_rev_major; + u_int8_t firmware_rev_minor; +} board_id_data_t; + +typedef struct { + u_int8_t dma_chan; +#define DMA_CHAN_5 0x20 +#define DMA_CHAN_6 0x40 +#define DMA_CHAN_7 0x80 + u_int8_t irq; +#define IRQ_9 0x01 +#define IRQ_10 0x02 +#define IRQ_11 0x04 +#define IRQ_12 0x08 +#define IRQ_14 0x20 +#define IRQ_15 0x40 + u_int8_t scsi_id; +} config_data_t; + +typedef struct { + u_int8_t enable; +} target_mode_params_t; + +typedef struct { + u_int8_t offset : 4, + period : 3, + sync : 1; +} targ_syncinfo_t; + +typedef struct { + u_int8_t initiate_sync : 1, + parity_enable : 1, + : 6; + + u_int8_t bus_transfer_rate; + u_int8_t time_on_bus; + u_int8_t time_off_bus; + u_int8_t num_mboxes; + u_int8_t mbox_base_addr[3]; + targ_syncinfo_t syncinfo[8]; + u_int8_t discinfo; + u_int8_t customer_sig[20]; + u_int8_t auto_retry; + u_int8_t board_switches; + u_int8_t firmware_cksum[2]; + u_int8_t bios_mbox_addr[3]; +} setup_data_t; + +struct aha_isa_port { + u_int16_t addr; + u_int8_t probed; +}; + +extern struct aha_isa_port aha_isa_ports[]; + +#define AHA_NUM_ISAPORTS 6 + +typedef enum { + BIO_330 = 0, + BIO_334 = 1, + BIO_230 = 2, + BIO_234 = 3, + BIO_130 = 4, + BIO_134 = 5, + BIO_DISABLED = 6, + BIO_DISABLED2 = 7 +} isa_compat_io_t; + +typedef struct { + u_int8_t sync_rate[16]; /* Sync in 10ns units */ +} target_sync_info_data_t; + +typedef struct { + u_int8_t len[3]; + u_int8_t addr[3]; +} aha_sg_t; + +/********************** Mail Box definitions *******************************/ + +typedef enum { + BMBO_FREE = 0x0, /* MBO intry is free */ + BMBO_START = 0x1, /* MBO activate entry */ + BMBO_ABORT = 0x2 /* MBO abort entry */ +} aha_mbo_action_code_t; + +typedef struct aha_mbox_out { + u_int8_t action_code; + u_int8_t ccb_addr[3]; +} aha_mbox_out_t; + +typedef enum { + BMBI_FREE = 0x0, /* MBI entry is free */ + BMBI_OK = 0x1, /* completed without error */ + BMBI_ABORT = 0x2, /* aborted ccb */ + BMBI_NOT_FOUND = 0x3, /* Tried to abort invalid CCB */ + BMBI_ERROR = 0x4 /* Completed with error */ +} aha_mbi_comp_code_t; + +typedef struct aha_mbox_in { + u_int8_t comp_code; + u_int8_t ccb_addr[3]; +} aha_mbox_in_t; + +/****************** Hardware CCB definition *********************************/ +typedef enum { + INITIATOR_CCB = 0x00, + INITIATOR_SG_CCB = 0x02, + INITIATOR_CCB_WRESID = 0x03, + INITIATOR_SG_CCB_WRESID = 0x04, + INITIATOR_BUS_DEV_RESET = 0x81 +} aha_ccb_opcode_t; + +typedef enum { + AHASTAT_NOERROR = 0x00, + AHASTAT_SELTIMEOUT = 0x11, + AHASTAT_DATARUN_ERROR = 0x12, + AHASTAT_UNEXPECTED_BUSFREE = 0x13, + AHASTAT_INVALID_PHASE = 0x14, + AHASTAT_INVALID_ACTION_CODE = 0x15, + AHASTAT_INVALID_OPCODE = 0x16, + AHASTAT_LINKED_CCB_LUN_MISMATCH = 0x17, + AHASTAT_INVALID_CCB_OR_SG_PARAM = 0x1A, + AHASTAT_HA_SCSI_BUS_RESET = 0x22, /* stolen from bt */ + AHASTAT_HA_BDR = 0x25 /* Stolen from bt */ +} ahastat_t; + +struct aha_hccb { + u_int8_t opcode; /* 0 */ + u_int8_t lun : 3, /* 1 */ + datain : 1, + dataout : 1, + target : 3; + u_int8_t cmd_len; /* 2 */ + u_int8_t sense_len; /* 3 */ + u_int8_t data_len[3]; /* 4 */ + u_int8_t data_addr[3]; /* 7 */ + u_int8_t link_ptr[3]; /* 10 */ + u_int8_t link_id; /* 13 */ + u_int8_t ahastat; /* 14 */ + u_int8_t sdstat; /* 15 */ + u_int8_t reserved1; /* 16 */ + u_int8_t reserved2; /* 17 */ + u_int8_t scsi_cdb[16]; /* 18 */ + u_int8_t sense_data[SSD_FULL_SIZE]; +}; + +typedef enum { + BCCB_FREE = 0x0, + BCCB_ACTIVE = 0x1, + BCCB_DEVICE_RESET = 0x2, + BCCB_RELEASE_SIMQ = 0x4 +} bccb_flags_t; + +struct aha_ccb { + struct aha_hccb hccb; /* hccb assumed to be at 0 */ + SLIST_ENTRY(aha_ccb) links; + u_int32_t flags; + union ccb *ccb; + bus_dmamap_t dmamap; + aha_sg_t *sg_list; + u_int32_t sg_list_phys; +}; + +struct sg_map_node { + bus_dmamap_t sg_dmamap; + bus_addr_t sg_physaddr; + aha_sg_t* sg_vaddr; + SLIST_ENTRY(sg_map_node) links; +}; + +struct aha_softc { + bus_space_tag_t tag; + bus_space_handle_t bsh; + struct cam_sim *sim; + struct cam_path *path; + aha_mbox_out_t *cur_outbox; + aha_mbox_in_t *cur_inbox; + aha_mbox_out_t *last_outbox; + aha_mbox_in_t *last_inbox; + struct aha_ccb *aha_ccb_array; + SLIST_HEAD(,aha_ccb) free_aha_ccbs; + LIST_HEAD(,ccb_hdr) pending_ccbs; + u_int32_t aha_ccb_physbase; + aha_mbox_in_t *in_boxes; + aha_mbox_out_t *out_boxes; + struct scsi_sense_data *sense_buffers; + u_int32_t sense_buffers_physbase; + struct aha_ccb *recovery_bccb; + u_int num_boxes; + bus_dma_tag_t parent_dmat; /* + * All dmat's derive from + * the dmat defined by our + * bus. + */ + bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */ + bus_dma_tag_t mailbox_dmat; /* dmat for our mailboxes */ + bus_dmamap_t mailbox_dmamap; + bus_dma_tag_t ccb_dmat; /* dmat for our ccb array */ + bus_dmamap_t ccb_dmamap; + bus_dma_tag_t sg_dmat; /* dmat for our sg maps */ + SLIST_HEAD(, sg_map_node) sg_maps; + bus_addr_t mailbox_physbase; + u_int num_ccbs; /* Number of CCBs malloc'd */ + u_int max_ccbs; /* Maximum allocatable CCBs */ + u_int max_sg; + u_int unit; + u_int scsi_id; + u_int32_t extended_trans :1, + wide_bus :1, + diff_bus :1, + ultra_scsi :1, + extended_lun :1, + strict_rr :1, + tag_capable :1, + wide_lun_ccb :1, + resource_shortage:1, + :23; + u_int16_t tags_permitted; + u_int16_t disc_permitted; + u_int16_t sync_permitted; + u_int16_t fast_permitted; + u_int16_t ultra_permitted; + u_int16_t wide_permitted; + u_int8_t init_level; + volatile u_int8_t command_cmp; + volatile u_int8_t latched_status; + u_int32_t bios_addr; + char firmware_ver[6]; + char model[32]; + u_int8_t boardid; +}; + +extern struct aha_softc *aha_softcs[]; /* XXX Config should handle this */ +extern u_long aha_unit; + +#define AHA_TEMP_UNIT 0xFF /* Unit for probes */ +struct aha_softc* aha_alloc(int unit, bus_space_tag_t tag, + bus_space_handle_t bsh); +void aha_free(struct aha_softc *aha); +int aha_probe(struct aha_softc *aha); +int aha_fetch_adapter_info(struct aha_softc *aha); +int aha_init(struct aha_softc *aha); +int aha_attach(struct aha_softc *aha); +void aha_intr(void *arg); +char * aha_name(struct aha_softc *aha); +int aha_check_probed_iop(u_int ioport); +void aha_mark_probed_bio(isa_compat_io_t port); +void aha_mark_probed_iop(u_int ioport); + +#define DEFAULT_CMD_TIMEOUT 10000 /* 1 sec */ +int aha_cmd(struct aha_softc *aha, aha_op_t opcode, + u_int8_t *params, u_int param_len, + u_int8_t *reply_data, u_int reply_len, + u_int cmd_timeout); + +#define aha_inb(aha, port) \ + bus_space_read_1((aha)->tag, (aha)->bsh, port) + +#define aha_outb(aha, port, value) \ + bus_space_write_1((aha)->tag, (aha)->bsh, port, value) + +#endif /* _AHA_H_ */ |