#define TWS_BIT0 0x00000001
#define TWS_BIT1 0x00000002
#define TWS_BIT2 0x00000004
#define TWS_BIT3 0x00000008
#define TWS_BIT4 0x00000010
#define TWS_BIT5 0x00000020
#define TWS_BIT6 0x00000040
#define TWS_BIT7 0x00000080
#define TWS_BIT8 0x00000100
#define TWS_BIT9 0x00000200
#define TWS_BIT10 0x00000400
#define TWS_BIT11 0x00000800
#define TWS_BIT12 0x00001000
#define TWS_BIT13 0x00002000
#define TWS_BIT14 0x00004000
#define TWS_BIT15 0x00008000
#define TWS_BIT16 0x00010000
#define TWS_BIT17 0x00020000
#define TWS_BIT18 0x00040000
#define TWS_BIT19 0x00080000
#define TWS_BIT20 0x00100000
#define TWS_BIT21 0x00200000
#define TWS_BIT22 0x00400000
#define TWS_BIT23 0x00800000
#define TWS_BIT24 0x01000000
#define TWS_BIT25 0x02000000
#define TWS_BIT26 0x04000000
#define TWS_BIT27 0x08000000
#define TWS_BIT28 0x10000000
#define TWS_BIT29 0x20000000
#define TWS_BIT30 0x40000000
#define TWS_BIT31 0x80000000
#define TWS_SENSE_DATA_LENGTH 18
#define TWS_ERROR_SPECIFIC_DESC_LEN 98
#define TWS_SENSE_SCSI_CURRENT_ERROR 0x70
#define TWS_SENSE_SCSI_DEFERRED_ERROR 0x71
#define TWS_SRC_CTRL_ERROR 3
#define TWS_SRC_CTRL_EVENT 4
#define TWS_SRC_FREEBSD_DRIVER 5
#define TWS_SRC_FREEBSD_OS 8
enum tws_sense_severity {
error = 1,
warning ,
info,
debug,
};
#define TWS_ERROR_LOGICAL_UNIT_NOT_SUPPORTED 0x010a
#define TWS_ERROR_NOT_SUPPORTED 0x010D
#define TWS_ERROR_UNIT_OFFLINE 0x0128
#define TWS_ERROR_MORE_DATA 0x0231
#define TWS_AEN_QUEUE_EMPTY 0x00
#define TWS_AEN_SOFT_RESET 0x01
#define TWS_AEN_SYNC_TIME_WITH_HOST 0x31
#define TWS_SEVERITY_ERROR 0x1
#define TWS_SEVERITY_WARNING 0x2
#define TWS_SEVERITY_INFO 0x3
#define TWS_SEVERITY_DEBUG 0x4
#define TWS_64BIT_SG_ADDRESSES 0x00000001
#define TWS_BIT_EXTEND 0x00000002
#define TWS_BASE_FW_SRL 24
#define TWS_BASE_FW_BRANCH 0
#define TWS_BASE_FW_BUILD 1
#define TWS_CURRENT_FW_SRL 41
#define TWS_CURRENT_FW_BRANCH 8
#define TWS_CURRENT_FW_BUILD 4
#define TWS_CURRENT_ARCH_ID 0x000A
#define TWS_FIFO_EMPTY 0xFFFFFFFFFFFFFFFFull
#define TWS_FIFO_EMPTY32 0xFFFFFFFFull
#define TWS_CONTROL_REGISTER_OFFSET 0x0
#define TWS_STATUS_REGISTER_OFFSET 0x4
#define TWS_COMMAND_QUEUE_OFFSET 0x8
#define TWS_RESPONSE_QUEUE_OFFSET 0xC
#define TWS_COMMAND_QUEUE_OFFSET_LOW 0x20
#define TWS_COMMAND_QUEUE_OFFSET_HIGH 0x24
#define TWS_LARGE_RESPONSE_QUEUE_OFFSET 0x30
#define TWS_I2O0_STATUS 0x0
#define TWS_I2O0_HIBDB 0x20
#define TWS_I2O0_HISTAT 0x30
#define TWS_I2O0_HIMASK 0x34
#define TWS_I2O0_HIBQP 0x40
#define TWS_I2O0_HOBQP 0x44
#define TWS_I2O0_CTL 0x74
#define TWS_I2O0_IOBDB 0x9C
#define TWS_I2O0_HOBDBC 0xA0
#define TWS_I2O0_SCRPD3 0xBC
#define TWS_I2O0_HIBQPL 0xC0
#define TWS_I2O0_HIBQPH 0xC4
#define TWS_I2O0_HOBQPL 0xC8
#define TWS_I2O0_HOBQPH 0xCC
#define TWS_I2O0_IOPOBQPL 0xD8
#define TWS_I2O0_IOPOBQPH 0xDC
#define TWS_I2O0_SRC_ADDRH 0xF8
#define TWS_MSG_ACC_MASK 0x20000000
#define TWS_32BIT_MASK 0xFFFFFFFF
#define TWS_FW_CMD_NOP 0x0
#define TWS_FW_CMD_INIT_CONNECTION 0x01
#define TWS_FW_CMD_EXECUTE_SCSI 0x10
#define TWS_FW_CMD_ATA_PASSTHROUGH 0x11
#define TWS_FW_CMD_GET_PARAM 0x12
#define TWS_FW_CMD_SET_PARAM 0x13
#define BUILD_SGL_OFF__OPCODE(sgl_off, opcode) \
((sgl_off << 5) & 0xE0) | (opcode & 0x1F)
#define BUILD_RES__OPCODE(res, opcode) \
((res << 5) & 0xE0) | (opcode & 0x1F)
#define GET_OPCODE(sgl_off__opcode) \
(sgl_off__opcode & 0x1F)
#define TWS_PARAM_VERSION_TABLE 0x0402
#define TWS_PARAM_VERSION_FW 3
#define TWS_PARAM_VERSION_BIOS 4
#define TWS_PARAM_CTLR_MODEL 8
#define TWS_PARAM_CONTROLLER_TABLE 0x0403
#define TWS_PARAM_CONTROLLER_PORT_COUNT 3
#define TWS_PARAM_TIME_TABLE 0x40A
#define TWS_PARAM_TIME_SCHED_TIME 0x3
#define TWS_PARAM_PHYS_TABLE 0x0001
#define TWS_PARAM_CONTROLLER_PHYS_COUNT 2
#define TWS_9K_PARAM_DESCRIPTOR 0x8000
#pragma pack(1)
struct tws_cmd_init_connect {
u_int8_t res1__opcode;
u_int8_t size;
u_int8_t request_id;
u_int8_t res2;
u_int8_t status;
u_int8_t flags;
u_int16_t message_credits;
u_int32_t features;
u_int16_t fw_srl;
u_int16_t fw_arch_id;
u_int16_t fw_branch;
u_int16_t fw_build;
u_int32_t result;
};
struct tws_cmd_download_firmware {
u_int8_t sgl_off__opcode;
u_int8_t size;
u_int8_t request_id;
u_int8_t unit;
u_int8_t status;
u_int8_t flags;
u_int16_t param;
u_int8_t sgl[1];
};
struct tws_cmd_reset_firmware {
u_int8_t res1__opcode;
u_int8_t size;
u_int8_t request_id;
u_int8_t unit;
u_int8_t status;
u_int8_t flags;
u_int8_t res2;
u_int8_t param;
};
struct tws_cmd_param {
u_int8_t sgl_off__opcode;
u_int8_t size;
u_int8_t request_id;
u_int8_t host_id__unit;
u_int8_t status;
u_int8_t flags;
u_int16_t param_count;
u_int8_t sgl[1];
};
struct tws_cmd_generic {
u_int8_t sgl_off__opcode;
u_int8_t size;
u_int8_t request_id;
u_int8_t host_id__unit;
u_int8_t status;
u_int8_t flags;
u_int16_t count;
};
struct tws_command_header {
u_int8_t sense_data[TWS_SENSE_DATA_LENGTH];
struct {
u_int16_t srcnum;
u_int8_t reserved;
u_int8_t status;
u_int16_t error;
u_int8_t res__srcid;
u_int8_t res__severity;
} status_block;
u_int8_t err_specific_desc[TWS_ERROR_SPECIFIC_DESC_LEN];
struct {
u_int8_t size_header;
u_int16_t request_id;
u_int8_t size_sense;
} header_desc;
};
union tws_command_giga {
struct tws_cmd_init_connect init_connect;
struct tws_cmd_download_firmware download_fw;
struct tws_cmd_reset_firmware reset_fw;
struct tws_cmd_param param;
struct tws_cmd_generic generic;
u_int8_t padding[1024 - sizeof(struct tws_command_header)];
};
struct tws_command_apache {
u_int8_t res__opcode;
u_int8_t unit;
u_int16_t lun_l4__req_id;
u_int8_t status;
u_int8_t sgl_offset;
u_int16_t lun_h4__sgl_entries;
u_int8_t cdb[16];
u_int8_t sg_list[744];
u_int8_t padding[128];
};
struct tws_command_packet {
struct tws_command_header hdr;
union {
union tws_command_giga pkt_g;
struct tws_command_apache pkt_a;
} cmd;
};
struct tws_getset_param {
u_int16_t table_id;
u_int8_t parameter_id;
u_int8_t reserved;
u_int16_t parameter_size_bytes;
u_int16_t parameter_actual_size_bytes;
u_int8_t data[1];
};
struct tws_outbound_response {
u_int32_t not_mfa :1;
u_int32_t reserved :7;
u_int32_t status :8;
u_int32_t request_id:16;
};
struct tws_sg_desc32 {
u_int32_t address;
u_int32_t length :24;
u_int32_t flag :8;
};
struct tws_sg_desc64 {
u_int64_t address;
u_int64_t length :32;
u_int64_t reserved :24;
u_int64_t flag :8;
};
struct tws_event_packet {
u_int32_t sequence_id;
u_int32_t time_stamp_sec;
u_int16_t aen_code;
u_int8_t severity;
u_int8_t retrieved;
u_int8_t repeat_count;
u_int8_t parameter_len;
u_int8_t parameter_data[TWS_ERROR_SPECIFIC_DESC_LEN];
u_int32_t event_src;
u_int8_t severity_str[20];
};
#pragma pack()
struct tws_sense {
struct tws_command_header *hdr;
u_int64_t hdr_pkt_phy;
};
struct tws_request {
struct tws_command_packet *cmd_pkt;
u_int64_t cmd_pkt_phy;
void *data;
u_int32_t length;
u_int32_t state;
u_int32_t type;
u_int32_t flags;
u_int32_t error_code;
u_int32_t request_id;
void (*cb)(struct tws_request *);
bus_dmamap_t dma_map;
union ccb *ccb_ptr;
struct callout timeout;
struct tws_softc *sc;
struct tws_request *next;
struct tws_request *prev;
};