1/*- 2 * Generic register and struct definitions for the Adaptech 1540, 1542, 3 * 1640, 1642 SCSI host adapters. Product specific probe and attach 4 * routines can be found in: 5 * aha_isa.c, aha_mca.c 6 * 7 * Derived from bt.c written by: 8 * 9 * Copyright (c) 1998 Justin T. Gibbs. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification, immediately at the beginning of the file. 18 * 2. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * $FreeBSD$ 34 */ 35 36#ifndef _AHAREG_H_ 37#define _AHAREG_H_ 38 39#include <sys/queue.h> 40#include <cam/scsi/scsi_all.h> 41 42#define AHA_MAXTRANSFER_SIZE 0xffffff /* limited by 24bit counter */ 43#define AHA_NSEG 17 /* The number of dma segments 44 * supported. */ 45#define ALL_TARGETS (~0) 46 47/* 48 * Control Register pp. 1-8, 1-9 (Write Only) 49 */ 50#define CONTROL_REG 0x00 51#define HARD_RESET 0x80 /* Hard Reset - return to POST state */ 52#define SOFT_RESET 0x40 /* Soft Reset - Clears Adapter state */ 53#define RESET_INTR 0x20 /* Reset/Ack Interrupt */ 54#define RESET_SBUS 0x10 /* Drive SCSI bus reset signal */ 55 56/* 57 * Status Register pp. 1-9, 1-10 (Read Only) 58 */ 59#define STATUS_REG 0x00 60#define DIAG_ACTIVE 0x80 /* Performing Internal Diags */ 61#define DIAG_FAIL 0x40 /* Internal Diags failed */ 62#define INIT_REQUIRED 0x20 /* MBOXes need initialization */ 63#define HA_READY 0x10 /* HA ready for new commands */ 64#define CMD_REG_BUSY 0x08 /* HA busy with last cmd byte */ 65#define DATAIN_REG_READY 0x04 /* Data-in Byte available */ 66#define STATUS_REG_RSVD 0x02 67#define CMD_INVALID 0x01 /* Invalid Command detected */ 68 69/* 70 * Command/Parameter Register pp. 1-10, 1-11 (Write Only) 71 */ 72#define COMMAND_REG 0x01 73 74/* 75 * Data in Register p. 1-11 (Read Only) 76 */ 77#define DATAIN_REG 0x01 78 79/* 80 * Interrupt Status Register pp. 1-12 -> 1-14 (Read Only) 81 */ 82#define INTSTAT_REG 0x02 83#define INTR_PENDING 0x80 /* There is a pending INTR */ 84#define INTSTAT_REG_RSVD 0x70 85#define SCSI_BUS_RESET 0x08 /* Bus Reset detected */ 86#define CMD_COMPLETE 0x04 87#define OMB_READY 0x02 /* Outgoin Mailbox Ready */ 88#define IMB_LOADED 0x01 /* Incoming Mailbox loaded */ 89 90/* 91 * Definitions for the "undocumented" geometry register, we just need 92 * its location. 93 */ 94#define GEOMETRY_REG 0x03 95 96#define AHA_NREGS (4) 97 98/* 99 * Opcodes for Adapter commands. 100 */ 101typedef enum { 102 AOP_NOP = 0x00, 103 AOP_INITIALIZE_MBOX = 0x01, 104 AOP_START_MBOX = 0x02, 105 AOP_EXECUTE_BIOS_CMD = 0x03, 106 AOP_INQUIRE_BOARD_ID = 0x04, 107 AOP_ENABLE_OMBR_INT = 0x05, 108 AOP_SET_SEL_TIMOUT = 0x06, 109 AOP_SET_TIME_ON_BUS = 0x07, 110 AOP_SET_TIME_OFF_BUS = 0x08, 111 AOP_SET_BUS_TRANS_RATE = 0x09, 112 AOP_INQUIRE_INST_LDEVS = 0x0A, 113 AOP_INQUIRE_CONFIG = 0x0B, 114 AOP_ENABLE_TARGET_MODE = 0x0C, 115 AOP_INQUIRE_SETUP_INFO = 0x0D, 116 AOP_WRITE_LRAM = 0x1A, 117 AOP_READ_LRAM = 0x1B, 118 AOP_WRITE_CHIP_FIFO = 0x1C, 119 AOP_READ_CHIP_FIFO = 0x1D, 120 AOP_ECHO_DATA_BYTE = 0x1F, 121 AOP_ADAPTER_DIAGNOSTICS = 0x20, 122 AOP_SET_ADAPTER_OPTIONS = 0x21, 123 AOP_SET_EEPROM = 0x22, 124 AOP_RETURN_EEPROM = 0x23, 125 AOP_ENABLE_SHADOW_RAM = 0x24, 126 AOP_INIT_BIOS_MBOX = 0x25, 127 AOP_SET_BIOS_BANK_1 = 0x26, 128 AOP_SET_BIOS_BANK_2 = 0x27, 129 AOP_RETURN_EXT_BIOS_INFO= 0x28, 130 AOP_MBOX_IF_ENABLE = 0x29, 131 AOP_SCSI_TERM_STATUS = 0x2C, 132 AOP_INQUIRE_SCAM_DEV = 0x2D, 133 AOP_SCSI_DEV_TABLE = 0x2E, 134 AOP_SCAM_OP = 0x2F, 135 AOP_START_BIOS_CMD = 0x82, 136 AOP_INQUIRE_ESETUP_INFO = 0x8D 137} aha_op_t; 138 139/************** Definitions of Multi-byte commands and responses ************/ 140 141struct aha_extbios 142{ 143 uint8_t flags; /* Bit 3 == 1 extended bios enabled */ 144 uint8_t mailboxlock; /* mail box lock code to unlock it */ 145}; 146 147typedef struct { 148 uint8_t num_mboxes; 149 uint8_t base_addr[3]; 150} init_24b_mbox_params_t; 151 152typedef struct { 153 uint8_t board_type; 154/* These values are mostly from the aha-1540CP technical reference, but */ 155/* with other values from the old aha1542.c driver. The values from the */ 156/* aha-1540CP technical manual are used where conflicts arise */ 157#define BOARD_1540_16HEAD_BIOS 0x00 158#define BOARD_1540_64HEAD_BIOS 0x30 159#define BOARD_1542 0x41 /* aha-1540/1542 w/64-h bios */ 160#define BOARD_1640 0x42 /* aha-1640 */ 161#define BOARD_1740 0x43 /* aha-1740A/1742A/1744 */ 162#define BOARD_1542C 0x44 /* aha-1542C */ 163#define BOARD_1542CF 0x45 /* aha-1542CF */ 164#define BOARD_1542CP 0x46 /* aha-1542CP, plug and play */ 165 uint8_t cust_features; 166#define FEATURES_STANDARD 0x30 167 uint8_t firmware_rev_major; 168 uint8_t firmware_rev_minor; 169} board_id_data_t; 170 171typedef struct { 172 uint8_t dma_chan; 173#define DMA_CHAN_5 0x20 174#define DMA_CHAN_6 0x40 175#define DMA_CHAN_7 0x80 176 uint8_t irq; 177#define IRQ_9 0x01 178#define IRQ_10 0x02 179#define IRQ_11 0x04 180#define IRQ_12 0x08 181#define IRQ_14 0x20 182#define IRQ_15 0x40 183 uint8_t scsi_id; 184} config_data_t; 185 186typedef struct { 187 uint8_t offset : 4, 188 period : 3, 189 sync : 1; 190} targ_syncinfo_t; 191 192typedef struct { 193 uint8_t initiate_sync : 1, 194 parity_enable : 1, 195 : 6; 196 197 uint8_t bus_transfer_rate; 198 uint8_t time_on_bus; 199 uint8_t time_off_bus; 200 uint8_t num_mboxes; 201 uint8_t mbox_base_addr[3]; 202 targ_syncinfo_t syncinfo[8]; 203 uint8_t discinfo; 204 uint8_t customer_sig[20]; 205 uint8_t auto_retry; 206 uint8_t board_switches; 207 uint8_t firmware_cksum[2]; 208 uint8_t bios_mbox_addr[3]; 209} setup_data_t; 210 211#define AHA_NUM_ISAPORTS 6 212 213typedef struct { 214 uint8_t len[3]; 215 uint8_t addr[3]; 216} aha_sg_t; 217 218/********************** Mail Box definitions *******************************/ 219 220typedef enum { 221 AMBO_FREE = 0x0, /* MBO intry is free */ 222 AMBO_START = 0x1, /* MBO activate entry */ 223 AMBO_ABORT = 0x2 /* MBO abort entry */ 224} aha_mbo_action_code_t; 225 226typedef struct aha_mbox_out { 227 uint8_t action_code; 228 uint8_t ccb_addr[3]; 229} aha_mbox_out_t; 230 231typedef enum { 232 AMBI_FREE = 0x0, /* MBI entry is free */ 233 AMBI_OK = 0x1, /* completed without error */ 234 AMBI_ABORT = 0x2, /* aborted ccb */ 235 AMBI_NOT_FOUND = 0x3, /* Tried to abort invalid CCB */ 236 AMBI_ERROR = 0x4 /* Completed with error */ 237} aha_mbi_comp_code_t; 238 239typedef struct aha_mbox_in { 240 uint8_t comp_code; 241 uint8_t ccb_addr[3]; 242} aha_mbox_in_t; 243 244/****************** Hardware CCB definition *********************************/ 245typedef enum { 246 INITIATOR_CCB = 0x00, 247 INITIATOR_SG_CCB = 0x02, 248 INITIATOR_CCB_WRESID = 0x03, 249 INITIATOR_SG_CCB_WRESID = 0x04, 250 INITIATOR_BUS_DEV_RESET = 0x81 251} aha_ccb_opcode_t; 252 253typedef enum { 254 AHASTAT_NOERROR = 0x00, 255 AHASTAT_SELTIMEOUT = 0x11, 256 AHASTAT_DATARUN_ERROR = 0x12, 257 AHASTAT_UNEXPECTED_BUSFREE = 0x13, 258 AHASTAT_INVALID_PHASE = 0x14, 259 AHASTAT_INVALID_ACTION_CODE = 0x15, 260 AHASTAT_INVALID_OPCODE = 0x16, 261 AHASTAT_LINKED_CCB_LUN_MISMATCH = 0x17, 262 AHASTAT_INVALID_CCB_OR_SG_PARAM = 0x1A, 263 AHASTAT_HA_SCSI_BUS_RESET = 0x22, /* stolen from bt */ 264 AHASTAT_HA_BDR = 0x25 /* Stolen from bt */ 265} ahastat_t; 266 267struct aha_hccb { 268 uint8_t opcode; /* 0 */ 269 uint8_t lun : 3, /* 1 */ 270 datain : 1, 271 dataout : 1, 272 target : 3; 273 uint8_t cmd_len; /* 2 */ 274 uint8_t sense_len; /* 3 */ 275 uint8_t data_len[3]; /* 4 */ 276 uint8_t data_addr[3]; /* 7 */ 277 uint8_t link_ptr[3]; /* 10 */ 278 uint8_t link_id; /* 13 */ 279 uint8_t ahastat; /* 14 */ 280 uint8_t sdstat; /* 15 */ 281 uint8_t reserved1; /* 16 */ 282 uint8_t reserved2; /* 17 */ 283 uint8_t scsi_cdb[16]; /* 18 */ 284 uint8_t sense_data[SSD_FULL_SIZE]; 285}; 286 287typedef enum { 288 ACCB_FREE = 0x0, 289 ACCB_ACTIVE = 0x1, 290 ACCB_DEVICE_RESET = 0x2, 291 ACCB_RELEASE_SIMQ = 0x4 292} accb_flags_t; 293 294struct aha_ccb { 295 struct aha_hccb hccb; /* hccb assumed to be at 0 */ 296 SLIST_ENTRY(aha_ccb) links; 297 uint32_t flags; 298 union ccb *ccb; 299 bus_dmamap_t dmamap; 300 struct callout timer; 301 aha_sg_t *sg_list; 302 uint32_t sg_list_phys; 303}; 304 305struct sg_map_node { 306 bus_dmamap_t sg_dmamap; 307 bus_addr_t sg_physaddr; 308 aha_sg_t* sg_vaddr; 309 SLIST_ENTRY(sg_map_node) links; 310}; 311 312struct aha_softc { 313 struct cam_sim *sim; 314 struct cam_path *path; 315 aha_mbox_out_t *cur_outbox; 316 aha_mbox_in_t *cur_inbox; 317 aha_mbox_out_t *last_outbox; 318 aha_mbox_in_t *last_inbox; 319 struct aha_ccb *aha_ccb_array; 320 SLIST_HEAD(,aha_ccb) free_aha_ccbs; 321 LIST_HEAD(,ccb_hdr) pending_ccbs; 322 u_int active_ccbs; 323 uint32_t aha_ccb_physbase; 324 aha_ccb_opcode_t ccb_sg_opcode; 325 aha_ccb_opcode_t ccb_ccb_opcode; 326 aha_mbox_in_t *in_boxes; 327 aha_mbox_out_t *out_boxes; 328 struct scsi_sense_data *sense_buffers; 329 uint32_t sense_buffers_physbase; 330 struct aha_ccb *recovery_accb; 331 u_int num_boxes; 332 bus_dma_tag_t parent_dmat; /* 333 * All dmat's derive from 334 * the dmat defined by our 335 * bus. 336 */ 337 bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */ 338 bus_dma_tag_t mailbox_dmat; /* dmat for our mailboxes */ 339 bus_dmamap_t mailbox_dmamap; 340 bus_dma_tag_t ccb_dmat; /* dmat for our ccb array */ 341 bus_dmamap_t ccb_dmamap; 342 bus_dma_tag_t sg_dmat; /* dmat for our sg maps */ 343 SLIST_HEAD(, sg_map_node) sg_maps; 344 bus_addr_t mailbox_physbase; 345 u_int num_ccbs; /* Number of CCBs malloc'd */ 346 u_int max_ccbs; /* Maximum allocatable CCBs */ 347 u_int max_sg; 348 u_int unit; 349 u_int scsi_id; 350 uint32_t extended_trans :1, 351 diff_bus :1, 352 extended_lun :1, 353 strict_rr :1, 354 tag_capable :1, 355 resource_shortage:1, 356 :26; 357 uint16_t disc_permitted; 358 uint16_t sync_permitted; 359 uint8_t init_level; 360 volatile uint8_t command_cmp; 361 volatile uint8_t latched_status; 362 uint32_t bios_addr; 363 uint8_t fw_major; 364 uint8_t fw_minor; 365 char model[32]; 366 uint8_t boardid; 367 struct resource *irq; 368 struct resource *port; 369 struct resource *drq; 370 int irqrid; 371 int portrid; 372 int drqrid; 373 void *ih; 374 device_t dev; 375 struct mtx lock; 376}; 377 378void aha_alloc(struct aha_softc *); 379int aha_attach(struct aha_softc *); 380int aha_cmd(struct aha_softc *, aha_op_t, uint8_t *, u_int, uint8_t *, u_int, 381 u_int); 382int aha_detach(struct aha_softc *); 383int aha_fetch_adapter_info(struct aha_softc *); 384void aha_find_probe_range(int, int *, int *); 385void aha_free(struct aha_softc *); 386int aha_init(struct aha_softc *); 387void aha_intr(void *); 388int aha_probe(struct aha_softc *); 389 390#define DEFAULT_CMD_TIMEOUT 10000 /* 1 sec */ 391 392#define aha_inb(aha, reg) \ 393 bus_read_1((aha)->port, reg) 394 395#define aha_outb(aha, reg, value) \ 396 bus_write_1((aha)->port, reg, value) 397 398#define ADP0100_PNP 0x00019004 /* ADP0100 */ 399#define AHA1540_PNP 0x40159004 /* ADP1540 */ 400#define AHA1542_PNP 0x42159004 /* ADP1542 */ 401#define AHA1542_PNPCOMPAT 0xA000D040 /* PNP00A0 */ 402#define ICU0091_PNP 0X91005AA4 /* ICU0091 */ 403 404#endif /* _AHAREG_H_ */ 405