187011Smsmith/*- 287011Smsmith * Copyright (c) 2001 Michael Smith 387011Smsmith * All rights reserved. 487011Smsmith * 587011Smsmith * Redistribution and use in source and binary forms, with or without 687011Smsmith * modification, are permitted provided that the following conditions 787011Smsmith * are met: 887011Smsmith * 1. Redistributions of source code must retain the above copyright 987011Smsmith * notice, this list of conditions and the following disclaimer. 1087011Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1187011Smsmith * notice, this list of conditions and the following disclaimer in the 1287011Smsmith * documentation and/or other materials provided with the distribution. 1387011Smsmith * 1487011Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1587011Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1687011Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1787011Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1887011Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1987011Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2087011Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2187011Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2287011Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2387011Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2487011Smsmith * SUCH DAMAGE. 2587011Smsmith * 2687011Smsmith * $FreeBSD$ 2787011Smsmith */ 2887011Smsmith 2987011Smsmith/* 3087011Smsmith * Structure and I/O definitions for the Command Interface for SCSI-3 Support. 3187011Smsmith * 3287011Smsmith * Data in command CDBs are in big-endian format. All other data is little-endian. 3387011Smsmith * This header only supports little-endian hosts at this time. 3487011Smsmith */ 3587011Smsmith 36128334Spsunion ciss_device_address 3787011Smsmith{ 3887011Smsmith struct /* MODE_PERIPHERAL and MODE_MASK_PERIPHERAL */ 3987011Smsmith { 4087011Smsmith u_int32_t target:24; /* SCSI target */ 4187011Smsmith u_int32_t bus:6; /* SCSI bus */ 4287011Smsmith u_int32_t mode:2; /* CISS_HDR_ADDRESS_MODE_* */ 4387011Smsmith u_int32_t extra_address; /* SCSI-3 level-2 and level-3 address bytes */ 4487011Smsmith } physical; 4587011Smsmith struct /* MODE_LOGICAL */ 4687011Smsmith { 4787011Smsmith u_int32_t lun:30; /* logical device ID */ 4887011Smsmith u_int32_t mode:2; /* CISS_HDR_ADDRESS_MODE_LOGICAL */ 4987011Smsmith u_int32_t :32; /* reserved */ 5087011Smsmith } logical; 5187011Smsmith struct 5287011Smsmith { 5387011Smsmith u_int32_t :30; 5487011Smsmith u_int32_t mode:2; 5587011Smsmith u_int32_t :32; 5687011Smsmith } mode; 5787011Smsmith}; 5887011Smsmith#define CISS_HDR_ADDRESS_MODE_PERIPHERAL 0x0 5987011Smsmith#define CISS_HDR_ADDRESS_MODE_LOGICAL 0x1 6087011Smsmith#define CISS_HDR_ADDRESS_MODE_MASK_PERIPHERAL 0x3 61128334Sps 62130874Sscottl#define CISS_EXTRA_MODE2(extra) ((extra & 0xc0000000) >> 30) 63130874Sscottl#define CISS_EXTRA_BUS2(extra) ((extra & 0x3f000000) >> 24) 64130874Sscottl#define CISS_EXTRA_TARGET2(extra) ((extra & 0x00ff0000) >> 16) 65130874Sscottl#define CISS_EXTRA_MODE3(extra) ((extra & 0x0000c000) >> 14) 66130874Sscottl#define CISS_EXTRA_BUS3(extra) ((extra & 0x00003f00) >> 8) 67130874Sscottl#define CISS_EXTRA_TARGET3(extra) ((extra & 0x000000ff)) 68130874Sscottl 69128334Spsstruct ciss_header 7087011Smsmith{ 7187011Smsmith u_int8_t :8; /* reserved */ 7287011Smsmith u_int8_t sg_in_list; /* SG's in the command structure */ 7387011Smsmith u_int16_t sg_total; /* total count of SGs for this command */ 7487011Smsmith u_int32_t host_tag; /* host identifier, bits 0&1 must be clear */ 7587011Smsmith#define CISS_HDR_HOST_TAG_ERROR (1<<1) 7687011Smsmith u_int32_t host_tag_zeroes; /* tag is 64 bits, but interface only supports 32 */ 7787011Smsmith union ciss_device_address address; 78103870Salfred} __packed; 7987011Smsmith 8087011Smsmithstruct ciss_cdb 8187011Smsmith{ 8287011Smsmith u_int8_t cdb_length; /* valid CDB bytes */ 8387011Smsmith u_int8_t type:3; 8487011Smsmith#define CISS_CDB_TYPE_COMMAND 0 8587011Smsmith#define CISS_CDB_TYPE_MESSAGE 1 8687011Smsmith u_int8_t attribute:3; 8787011Smsmith#define CISS_CDB_ATTRIBUTE_UNTAGGED 0 8887011Smsmith#define CISS_CDB_ATTRIBUTE_SIMPLE 4 8987011Smsmith#define CISS_CDB_ATTRIBUTE_HEAD_OF_QUEUE 5 9087011Smsmith#define CISS_CDB_ATTRIBUTE_ORDERED 6 9187011Smsmith#define CISS_CDB_ATTRIBUTE_AUTO_CONTINGENT 7 9287011Smsmith u_int8_t direction:2; 9387011Smsmith#define CISS_CDB_DIRECTION_NONE 0 94123307Sps#define CISS_CDB_DIRECTION_WRITE 1 95123307Sps#define CISS_CDB_DIRECTION_READ 2 9687011Smsmith u_int16_t timeout; /* seconds */ 9787011Smsmith#define CISS_CDB_BUFFER_SIZE 16 9887011Smsmith u_int8_t cdb[CISS_CDB_BUFFER_SIZE]; 99103870Salfred} __packed; 10087011Smsmith 10187011Smsmithstruct ciss_error_info_pointer 10287011Smsmith{ 10387011Smsmith u_int64_t error_info_address; /* points to ciss_error_info structure */ 10487011Smsmith u_int32_t error_info_length; 105103870Salfred} __packed; 10687011Smsmith 10787011Smsmithstruct ciss_error_info 10887011Smsmith{ 10987011Smsmith u_int8_t scsi_status; 11087011Smsmith#define CISS_SCSI_STATUS_GOOD 0x00 /* these are scsi-standard values */ 11187011Smsmith#define CISS_SCSI_STATUS_CHECK_CONDITION 0x02 11287011Smsmith#define CISS_SCSI_STATUS_CONDITION_MET 0x04 11387011Smsmith#define CISS_SCSI_STATUS_BUSY 0x08 11487011Smsmith#define CISS_SCSI_STATUS_INDETERMINATE 0x10 11587011Smsmith#define CISS_SCSI_STATUS_INDETERMINATE_CM 0x14 11687011Smsmith#define CISS_SCSI_STATUS_RESERVATION_CONFLICT 0x18 11787011Smsmith#define CISS_SCSI_STATUS_COMMAND_TERMINATED 0x22 11887011Smsmith#define CISS_SCSI_STATUS_QUEUE_FULL 0x28 11987011Smsmith#define CISS_SCSI_STATUS_ACA_ACTIVE 0x30 12087011Smsmith u_int8_t sense_length; 12187011Smsmith u_int16_t command_status; 12287011Smsmith#define CISS_CMD_STATUS_SUCCESS 0 12387011Smsmith#define CISS_CMD_STATUS_TARGET_STATUS 1 12487011Smsmith#define CISS_CMD_STATUS_DATA_UNDERRUN 2 12587011Smsmith#define CISS_CMD_STATUS_DATA_OVERRUN 3 12687011Smsmith#define CISS_CMD_STATUS_INVALID_COMMAND 4 12787011Smsmith#define CISS_CMD_STATUS_PROTOCOL_ERROR 5 12887011Smsmith#define CISS_CMD_STATUS_HARDWARE_ERROR 6 12987011Smsmith#define CISS_CMD_STATUS_CONNECTION_LOST 7 13087011Smsmith#define CISS_CMD_STATUS_ABORTED 8 13187011Smsmith#define CISS_CMD_STATUS_ABORT_FAILED 9 13287011Smsmith#define CISS_CMD_STATUS_UNSOLICITED_ABORT 10 13387011Smsmith#define CISS_CMD_STATUS_TIMEOUT 11 13487011Smsmith#define CISS_CMD_STATUS_UNABORTABLE 12 13587011Smsmith u_int32_t residual_count; 13687011Smsmith union { 13787011Smsmith struct { 13887011Smsmith u_int8_t res1[3]; 13987011Smsmith u_int8_t type; 14087011Smsmith u_int32_t error_info; 141132829Sps } __packed common_info; 14287011Smsmith struct { 14387011Smsmith u_int8_t res1[2]; 14487011Smsmith u_int8_t offense_size; 14587011Smsmith u_int8_t offense_offset; 14687011Smsmith u_int32_t offense_value; 147132829Sps } __packed invalid_command; 14887011Smsmith } additional_error_info; 14987011Smsmith u_int8_t sense_info[0]; 150103870Salfred} __packed; 15187011Smsmith 15287011Smsmithstruct ciss_sg_entry 15387011Smsmith{ 15487011Smsmith u_int64_t address; 15587011Smsmith#define CISS_SG_ADDRESS_BITBUCKET (~(u_int64_t)0) 15687011Smsmith u_int32_t length; 15787011Smsmith u_int32_t :31; 15887011Smsmith u_int32_t extension:1; /* address points to another s/g chain */ 159103870Salfred} __packed; 16087011Smsmith 16187011Smsmithstruct ciss_command 16287011Smsmith{ 16387011Smsmith struct ciss_header header; 16487011Smsmith struct ciss_cdb cdb; 16587011Smsmith struct ciss_error_info_pointer error_info; 16687011Smsmith struct ciss_sg_entry sg[0]; 167103870Salfred} __packed; 16887011Smsmith 16987011Smsmith#define CISS_OPCODE_REPORT_LOGICAL_LUNS 0xc2 17087011Smsmith#define CISS_OPCODE_REPORT_PHYSICAL_LUNS 0xc3 17187011Smsmith 172128334Spsstruct ciss_lun_report 17387011Smsmith{ 17487011Smsmith u_int32_t list_size; /* big-endian */ 17587011Smsmith u_int32_t :32; 17687011Smsmith union ciss_device_address lun[0]; 177103870Salfred} __packed; 17887011Smsmith 179110366Sps#define CISS_VPD_LOGICAL_DRIVE_GEOMETRY 0xc1 180110366Spsstruct ciss_ldrive_geometry 181110366Sps{ 182110366Sps u_int8_t periph_qualifier:3; 183110366Sps u_int8_t periph_devtype:5; 184110366Sps u_int8_t page_code; 185110366Sps u_int8_t res1; 186110366Sps u_int8_t page_length; 187110366Sps u_int16_t cylinders; /* big-endian */ 188110366Sps u_int8_t heads; 189110366Sps u_int8_t sectors; 190110366Sps u_int8_t fault_tolerance; 191110366Sps u_int8_t res2[3]; 192110366Sps} __attribute__ ((packed)); 193110366Sps 194128334Spsstruct ciss_report_cdb 19587011Smsmith{ 19687011Smsmith u_int8_t opcode; 19787011Smsmith u_int8_t reserved[5]; 19887011Smsmith u_int32_t length; /* big-endian */ 19987011Smsmith u_int8_t :8; 20087011Smsmith u_int8_t control; 201103870Salfred} __packed; 20287011Smsmith 20387011Smsmith/* 20487011Smsmith * Note that it's not clear whether we have to set the detail field to 20587011Smsmith * the tag of the command to be aborted, or the tag field in the command itself; 20687011Smsmith * documentation conflicts on this. 20787011Smsmith */ 20887011Smsmith#define CISS_OPCODE_MESSAGE_ABORT 0x00 20987011Smsmith#define CISS_MESSAGE_ABORT_TASK 0x00 210128334Sps#define CISS_MESSAGE_ABORT_TASK_SET 0x01 21187011Smsmith#define CISS_MESSAGE_ABORT_CLEAR_ACA 0x02 21287011Smsmith#define CISS_MESSAGE_ABORT_CLEAR_TASK_SET 0x03 21387011Smsmith 21487011Smsmith#define CISS_OPCODE_MESSAGE_RESET 0x01 21587011Smsmith#define CISS_MESSAGE_RESET_CONTROLLER 0x00 21687011Smsmith#define CISS_MESSAGE_RESET_BUS 0x01 21787011Smsmith#define CISS_MESSAGE_RESET_TARGET 0x03 21887011Smsmith#define CISS_MESSAGE_RESET_LOGICAL_UNIT 0x04 21987011Smsmith 22087011Smsmith#define CISS_OPCODE_MESSAGE_SCAN 0x02 22187011Smsmith#define CISS_MESSAGE_SCAN_CONTROLLER 0x00 22287011Smsmith#define CISS_MESSAGE_SCAN_BUS 0x01 22387011Smsmith#define CISS_MESSAGE_SCAN_TARGET 0x03 22487011Smsmith#define CISS_MESSAGE_SCAN_LOGICAL_UNIT 0x04 22587011Smsmith 22687011Smsmith#define CISS_OPCODE_MESSAGE_NOP 0x03 22787011Smsmith 228128334Spsstruct ciss_message_cdb 22987011Smsmith{ 23087011Smsmith u_int8_t opcode; 23187011Smsmith u_int8_t type; 23287011Smsmith u_int16_t :16; 23387011Smsmith u_int32_t abort_tag; /* XXX endianness? */ 23487011Smsmith u_int8_t reserved[8]; 235103870Salfred} __packed; 23687011Smsmith 23787011Smsmith/* 23887011Smsmith * CISS vendor-specific commands/messages. 23987011Smsmith * 24087011Smsmith * Note that while messages and vendor-specific commands are 24187011Smsmith * differentiated, they are handled in basically the same way and can 24287011Smsmith * be considered to be basically the same thing, as long as the cdb 24387011Smsmith * type field is set correctly. 24487011Smsmith */ 24587011Smsmith#define CISS_OPCODE_READ 0xc0 24687011Smsmith#define CISS_OPCODE_WRITE 0xc1 24787011Smsmith#define CISS_COMMAND_NOTIFY_ON_EVENT 0xd0 24887011Smsmith#define CISS_COMMAND_ABORT_NOTIFY 0xd1 24987011Smsmith 250128334Spsstruct ciss_notify_cdb 25187011Smsmith{ 25287011Smsmith u_int8_t opcode; 25387011Smsmith u_int8_t command; 25487011Smsmith u_int8_t res1[2]; 25587011Smsmith u_int16_t timeout; /* seconds, little-endian */ 25687011Smsmith u_int8_t res2; /* reserved */ 25787011Smsmith u_int8_t synchronous:1; /* return immediately */ 25887011Smsmith u_int8_t ordered:1; /* return events in recorded order */ 25987011Smsmith u_int8_t seek_to_oldest:1; /* reset read counter to oldest event */ 26087011Smsmith u_int8_t new_only:1; /* ignore any queued events */ 26187011Smsmith u_int8_t :4; 26287011Smsmith u_int32_t length; /* must be 512, little-endian */ 26387011Smsmith#define CISS_NOTIFY_DATA_SIZE 512 26487011Smsmith u_int8_t control; 265103870Salfred} __packed; 26687011Smsmith 26787011Smsmith#define CISS_NOTIFY_NOTIFIER 0 26887011Smsmith#define CISS_NOTIFY_NOTIFIER_STATUS 0 26987011Smsmith#define CISS_NOTIFY_NOTIFIER_PROTOCOL 1 27087011Smsmith 27187011Smsmith#define CISS_NOTIFY_HOTPLUG 1 27287011Smsmith#define CISS_NOTIFY_HOTPLUG_PHYSICAL 0 27387011Smsmith#define CISS_NOTIFY_HOTPLUG_POWERSUPPLY 1 27487011Smsmith#define CISS_NOTIFY_HOTPLUG_FAN 2 27587011Smsmith#define CISS_NOTIFY_HOTPLUG_POWER 3 27687011Smsmith#define CISS_NOTIFY_HOTPLUG_REDUNDANT 4 277129796Sps#define CISS_NOTIFY_HOTPLUG_NONDISK 5 27887011Smsmith 27987011Smsmith#define CISS_NOTIFY_HARDWARE 2 28087011Smsmith#define CISS_NOTIFY_HARDWARE_CABLES 0 28187011Smsmith#define CISS_NOTIFY_HARDWARE_MEMORY 1 28287011Smsmith#define CISS_NOTIFY_HARDWARE_FAN 2 28387011Smsmith#define CISS_NOTIFY_HARDWARE_VRM 3 28487011Smsmith 28587011Smsmith#define CISS_NOTIFY_ENVIRONMENT 3 28687011Smsmith#define CISS_NOTIFY_ENVIRONMENT_TEMPERATURE 0 28787011Smsmith#define CISS_NOTIFY_ENVIRONMENT_POWERSUPPLY 1 28887011Smsmith#define CISS_NOTIFY_ENVIRONMENT_CHASSIS 2 28987011Smsmith#define CISS_NOTIFY_ENVIRONMENT_POWER 3 29087011Smsmith 29187011Smsmith#define CISS_NOTIFY_PHYSICAL 4 29287011Smsmith#define CISS_NOTIFY_PHYSICAL_STATE 0 29387011Smsmith 29487011Smsmith#define CISS_NOTIFY_LOGICAL 5 29587011Smsmith#define CISS_NOTIFY_LOGICAL_STATUS 0 29687011Smsmith#define CISS_NOTIFY_LOGICAL_ERROR 1 29787011Smsmith#define CISS_NOTIFY_LOGICAL_SURFACE 2 29887011Smsmith 29987011Smsmith#define CISS_NOTIFY_REDUNDANT 6 30087011Smsmith#define CISS_NOTIFY_REDUNDANT_STATUS 0 30187011Smsmith 30287011Smsmith#define CISS_NOTIFY_CISS 8 30387011Smsmith#define CISS_NOTIFY_CISS_REDUNDANT_CHANGE 0 30487011Smsmith#define CISS_NOTIFY_CISS_PATH_STATUS 1 30587011Smsmith#define CISS_NOTIFY_CISS_HARDWARE_ERROR 2 30687011Smsmith#define CISS_NOTIFY_CISS_LOGICAL 3 30787011Smsmith 30887011Smsmithstruct ciss_notify_drive 30987011Smsmith{ 31087011Smsmith u_int16_t physical_drive_number; 31187011Smsmith u_int8_t configured_drive_flag; 31287011Smsmith u_int8_t spare_drive_flag; 31387011Smsmith u_int8_t big_physical_drive_number; 31487011Smsmith u_int8_t enclosure_bay_number; 315103870Salfred} __packed; 31687011Smsmith 31787011Smsmithstruct ciss_notify_locator 31887011Smsmith{ 31987011Smsmith u_int16_t port; 32087011Smsmith u_int16_t id; 32187011Smsmith u_int16_t box; 322103870Salfred} __packed; 32387011Smsmith 32487011Smsmithstruct ciss_notify_redundant_controller 32587011Smsmith{ 32687011Smsmith u_int16_t slot; 327103870Salfred} __packed; 32887011Smsmith 32987011Smsmithstruct ciss_notify_logical_status 33087011Smsmith{ 33187011Smsmith u_int16_t logical_drive; 33287011Smsmith u_int8_t previous_state; 33387011Smsmith u_int8_t new_state; 33487011Smsmith u_int8_t spare_state; 335103870Salfred} __packed; 336128334Sps 33787011Smsmithstruct ciss_notify_rebuild_aborted 33887011Smsmith{ 33987011Smsmith u_int16_t logical_drive; 34087011Smsmith u_int8_t replacement_drive; 34187011Smsmith u_int8_t error_drive; 34287011Smsmith u_int8_t big_replacement_drive; 34387011Smsmith u_int8_t big_error_drive; 344103870Salfred} __packed; 34587011Smsmith 346128334Spsstruct ciss_notify_io_error 34787011Smsmith{ 34887011Smsmith u_int16_t logical_drive; 34987011Smsmith u_int32_t lba; 35087011Smsmith u_int16_t block_count; 35187011Smsmith u_int8_t command; 35287011Smsmith u_int8_t failure_bus; 35387011Smsmith u_int8_t failure_drive; 35487011Smsmith u_int64_t big_lba; 355103870Salfred} __packed; 35687011Smsmith 35787011Smsmithstruct ciss_notify_consistency_completed 35887011Smsmith{ 35987011Smsmith u_int16_t logical_drive; 360103870Salfred} __packed; 36187011Smsmith 362128334Spsstruct ciss_notify 36387011Smsmith{ 36487011Smsmith u_int32_t timestamp; /* seconds since controller power-on */ 36587011Smsmith u_int16_t class; 36687011Smsmith u_int16_t subclass; 36787011Smsmith u_int16_t detail; 368128334Sps union 36987011Smsmith { 37087011Smsmith struct ciss_notify_drive drive; 37187011Smsmith struct ciss_notify_locator location; 37287011Smsmith struct ciss_notify_redundant_controller redundant_controller; 37387011Smsmith struct ciss_notify_logical_status logical_status; 37487011Smsmith struct ciss_notify_rebuild_aborted rebuild_aborted; 37587011Smsmith struct ciss_notify_io_error io_error; 37687011Smsmith struct ciss_notify_consistency_completed consistency_completed; 37787011Smsmith u_int8_t data[64]; 37887011Smsmith } data; 37987011Smsmith char message[80]; 38087011Smsmith u_int32_t tag; 38187011Smsmith u_int16_t date; 38287011Smsmith u_int16_t year; 38387011Smsmith u_int32_t time; 38487011Smsmith u_int16_t pre_power_up_time; 38587011Smsmith union ciss_device_address device; 38687011Smsmith /* XXX pads to 512 bytes */ 387103870Salfred} __packed; 38887011Smsmith 38987011Smsmith/* 390128334Sps * CISS config table, which describes the controller's 39187011Smsmith * supported interface(s) and capabilities. 39287011Smsmith * 39387011Smsmith * This is mapped directly via PCI. 39487011Smsmith */ 395128334Spsstruct ciss_config_table 39687011Smsmith{ 39787011Smsmith char signature[4]; /* "CISS" */ 39887011Smsmith u_int32_t valence; 39987011Smsmith u_int32_t supported_methods; 40087011Smsmith#define CISS_TRANSPORT_METHOD_READY (1<<0) 401128334Sps#define CISS_TRANSPORT_METHOD_SIMPLE (1<<1) 402180454Sscottl#define CISS_TRANSPORT_METHOD_PERF (1<<2) 40387011Smsmith u_int32_t active_method; 40487011Smsmith u_int32_t requested_method; 40587011Smsmith u_int32_t command_physlimit; 40687011Smsmith u_int32_t interrupt_coalesce_delay; 40787011Smsmith u_int32_t interrupt_coalesce_count; 40887011Smsmith u_int32_t max_outstanding_commands; 40987011Smsmith u_int32_t bus_types; 41087011Smsmith#define CISS_TRANSPORT_BUS_TYPE_ULTRA2 (1<<0) 41187011Smsmith#define CISS_TRANSPORT_BUS_TYPE_ULTRA3 (1<<1) 41287011Smsmith#define CISS_TRANSPORT_BUS_TYPE_FIBRE1 (1<<8) 41387011Smsmith#define CISS_TRANSPORT_BUS_TYPE_FIBRE2 (1<<9) 414129345Sps u_int32_t transport_offset; 415129345Sps char server_name[16]; 416129345Sps u_int32_t heartbeat; 41787011Smsmith u_int32_t host_driver; 41887011Smsmith#define CISS_DRIVER_SUPPORT_UNIT_ATTENTION (1<<0) 41987011Smsmith#define CISS_DRIVER_QUICK_INIT (1<<1) 42087011Smsmith#define CISS_DRIVER_INTERRUPT_ON_LOCKUP (1<<2) 42187011Smsmith#define CISS_DRIVER_SUPPORT_MIXED_Q_TAGS (1<<3) 42287011Smsmith#define CISS_DRIVER_HOST_IS_ALPHA (1<<4) 423129345Sps#define CISS_DRIVER_MULTI_LUN_SUPPORT (1<<5) 424129345Sps#define CISS_DRIVER_MESSAGE_REQUESTS_SUPPORTED (1<<7) 425129345Sps#define CISS_DRIVER_DAUGHTER_ATTACHED (1<<8) 426129345Sps#define CISS_DRIVER_SCSI_PREFETCH (1<<9) 427129345Sps u_int32_t max_sg_length; /* 31 in older firmware */ 428245459Ssbruno/* 429245459Ssbruno * these fields appear in OpenCISS Spec 1.06 430245459Ssbruno * http://cciss.sourceforge.net/#docs 431245459Ssbruno */ 432245459Ssbruno u_int32_t max_logical_supported; 433245459Ssbruno u_int32_t max_physical_supported; 434245459Ssbruno u_int32_t max_physical_per_logical; 435245459Ssbruno u_int32_t max_perfomant_mode_cmds; 436245459Ssbruno u_int32_t max_block_fetch_count; 437103870Salfred} __packed; 43887011Smsmith 43987011Smsmith/* 440180454Sscottl * Configuration table for the Performant transport. Only 4 request queues 441180454Sscottl * are mentioned in this table, though apparently up to 256 can exist. 442180454Sscottl */ 443180454Sscottlstruct ciss_perf_config { 444180454Sscottl uint32_t fetch_count[8]; 445180454Sscottl#define CISS_SG_FETCH_MAX 0 446180454Sscottl#define CISS_SG_FETCH_1 1 447180454Sscottl#define CISS_SG_FETCH_2 2 448180454Sscottl#define CISS_SG_FETCH_4 3 449180454Sscottl#define CISS_SG_FETCH_8 4 450180454Sscottl#define CISS_SG_FETCH_16 5 451180454Sscottl#define CISS_SG_FETCH_32 6 452180454Sscottl#define CISS_SG_FETCH_NONE 7 453180454Sscottl uint32_t rq_size; 454180454Sscottl uint32_t rq_count; 455180454Sscottl uint32_t rq_bank_lo; 456180454Sscottl uint32_t rq_bank_hi; 457180454Sscottl struct { 458180454Sscottl uint32_t rq_addr_lo; 459180454Sscottl uint32_t rq_addr_hi; 460180454Sscottl } __packed rq[4]; 461180454Sscottl} __packed; 462180454Sscottl 463180454Sscottl/* 46487011Smsmith * In a flagrant violation of what CISS seems to be meant to be about, 46587011Smsmith * Compaq recycle a goodly portion of their previous generation's 46687011Smsmith * command set (and all the legacy baggage related to a design 46787011Smsmith * originally aimed at narrow SCSI) through the Array Controller Read 46887011Smsmith * and Array Controller Write interface. 46987011Smsmith * 47087011Smsmith * Command ID values here can be looked up for in the 47187011Smsmith * publically-available documentation for the older controllers; note 47287011Smsmith * that the command layout is necessarily different to fit within the 47387011Smsmith * CDB. 47487011Smsmith */ 47587011Smsmith#define CISS_ARRAY_CONTROLLER_READ 0x26 47687011Smsmith#define CISS_ARRAY_CONTROLLER_WRITE 0x27 47787011Smsmith 47887011Smsmith#define CISS_BMIC_ID_LDRIVE 0x10 47987011Smsmith#define CISS_BMIC_ID_CTLR 0x11 48087011Smsmith#define CISS_BMIC_ID_LSTATUS 0x12 48187011Smsmith#define CISS_BMIC_ID_PDRIVE 0x15 48287011Smsmith#define CISS_BMIC_BLINK_PDRIVE 0x16 48387011Smsmith#define CISS_BMIC_SENSE_BLINK_PDRIVE 0x17 484145258Sps#define CISS_BMIC_SOFT_RESET 0x40 48587011Smsmith#define CISS_BMIC_FLUSH_CACHE 0xc2 48687011Smsmith#define CISS_BMIC_ACCEPT_MEDIA 0xe0 48787011Smsmith 48887011Smsmith/* 48987011Smsmith * When numbering drives, the original design assumed that 49087011Smsmith * drives 0-7 are on the first SCSI bus, 8-15 on the second, 49187011Smsmith * and so forth. In order to handle modern SCSI configurations, 49287011Smsmith * the MSB is set in the drive ID field, in which case the 49387011Smsmith * modulus changes from 8 to the number of supported drives 49487011Smsmith * per SCSI bus (as obtained from the ID_CTLR command). 49587011Smsmith * This feature is referred to as BIG_MAP support, and we assume 49687011Smsmith * that all CISS controllers support it. 49787011Smsmith */ 49887011Smsmith 49987011Smsmith#define CISS_BIG_MAP_ID(sc, bus, target) \ 50087011Smsmith (0x80 | \ 50187011Smsmith ((sc)->ciss_id->drives_per_scsi_bus * (bus)) | \ 50287011Smsmith (target)) 50387011Smsmith 50487011Smsmith#define CISS_BIG_MAP_BUS(sc, id) \ 50587011Smsmith (((id) & 0x80) ? (((id) & ~0x80) / (sc)->ciss_id->drives_per_scsi_bus) : -1) 50687011Smsmith 50787011Smsmith#define CISS_BIG_MAP_TARGET(sc, id) \ 50887011Smsmith (((id) & 0x80) ? (((id) & ~0x80) % (sc)->ciss_id->drives_per_scsi_bus) : -1) 50987011Smsmith 51087011Smsmith#define CISS_BIG_MAP_ENTRIES 128 /* number of entries in a BIG_MAP */ 51187011Smsmith 51287011Smsmith/* 513128337Sps * In the device address of a logical volume, the bus number 514128337Sps * is encoded into the logical lun volume number starting 515128337Sps * at the second byte, with the first byte defining the 516128337Sps * logical drive number. 517128337Sps */ 518128337Sps#define CISS_LUN_TO_BUS(x) (((x) >> 16) & 0xFF) 519128337Sps#define CISS_LUN_TO_TARGET(x) ((x) & 0xFF) 520128337Sps 521128337Sps/* 52287011Smsmith * BMIC CDB 52387011Smsmith * 52487011Smsmith * Note that the phys_drive/res1 field is nominally the 32-bit 52587011Smsmith * "block number" field, but the only BMIC command(s) of interest 526128334Sps * implemented overload the MSB (note big-endian format here) 52787011Smsmith * to be the physical drive ID, so we define accordingly. 52887011Smsmith */ 52987011Smsmithstruct ciss_bmic_cdb { 53087011Smsmith u_int8_t opcode; 53187011Smsmith u_int8_t log_drive; 53287011Smsmith u_int8_t phys_drive; 53387011Smsmith u_int8_t res1[3]; 53487011Smsmith u_int8_t bmic_opcode; 53587011Smsmith u_int16_t size; /* big-endian */ 53687011Smsmith u_int8_t res2; 537103870Salfred} __packed; 53887011Smsmith 53987011Smsmith/* 54087011Smsmith * BMIC command command/return structures. 54187011Smsmith */ 54287011Smsmith 54387011Smsmith/* CISS_BMIC_ID_LDRIVE */ 54487011Smsmithstruct ciss_bmic_id_ldrive { 54587011Smsmith u_int16_t block_size; 54687011Smsmith u_int32_t blocks_available; 54787011Smsmith u_int8_t drive_parameter_table[16]; /* XXX define */ 54887011Smsmith u_int8_t fault_tolerance; 54987011Smsmith#define CISS_LDRIVE_RAID0 0 55087011Smsmith#define CISS_LDRIVE_RAID4 1 55187011Smsmith#define CISS_LDRIVE_RAID1 2 55287011Smsmith#define CISS_LDRIVE_RAID5 3 553123298Sps#define CISS_LDRIVE_RAID51 4 554123298Sps#define CISS_LDRIVE_RAIDADG 5 555130081Sps u_int8_t res1; 556130081Sps u_int8_t bios_disable_flag; 557130081Sps u_int8_t res2; 55887011Smsmith u_int32_t logical_drive_identifier; 55987011Smsmith char logical_drive_label[64]; 560130081Sps u_int64_t big_blocks_available; 561130081Sps u_int8_t res3[410]; 562103870Salfred} __packed; 56387011Smsmith 56487011Smsmith/* CISS_BMIC_ID_LSTATUS */ 56587011Smsmithstruct ciss_bmic_id_lstatus { 56687011Smsmith u_int8_t status; 56787011Smsmith#define CISS_LSTATUS_OK 0 56887011Smsmith#define CISS_LSTATUS_FAILED 1 56987011Smsmith#define CISS_LSTATUS_NOT_CONFIGURED 2 57087011Smsmith#define CISS_LSTATUS_INTERIM_RECOVERY 3 57187011Smsmith#define CISS_LSTATUS_READY_RECOVERY 4 57287011Smsmith#define CISS_LSTATUS_RECOVERING 5 57387011Smsmith#define CISS_LSTATUS_WRONG_PDRIVE 6 57487011Smsmith#define CISS_LSTATUS_MISSING_PDRIVE 7 57587011Smsmith#define CISS_LSTATUS_EXPANDING 10 57687011Smsmith#define CISS_LSTATUS_BECOMING_READY 11 57787011Smsmith#define CISS_LSTATUS_QUEUED_FOR_EXPANSION 12 57887011Smsmith u_int32_t deprecated_drive_failure_map; 57987011Smsmith u_int8_t res1[416]; 58087011Smsmith u_int32_t blocks_to_recover; 58187011Smsmith u_int8_t deprecated_drive_rebuilding; 58287011Smsmith u_int16_t deprecated_remap_count[32]; 58387011Smsmith u_int32_t deprecated_replacement_map; 58487011Smsmith u_int32_t deprecated_active_spare_map; 58587011Smsmith u_int8_t spare_configured:1; 58687011Smsmith u_int8_t spare_rebuilding:1; 58787011Smsmith u_int8_t spare_rebuilt:1; 58887011Smsmith u_int8_t spare_failed:1; 58987011Smsmith u_int8_t spare_switched:1; 59087011Smsmith u_int8_t spare_available:1; 59187011Smsmith u_int8_t res2:2; 59287011Smsmith u_int8_t deprecated_spare_to_replace_map[32]; 59387011Smsmith u_int32_t deprecated_replaced_marked_ok_map; 59487011Smsmith u_int8_t media_exchanged; 59587011Smsmith u_int8_t cache_failure; 59687011Smsmith u_int8_t expand_failure; 59787011Smsmith u_int8_t rebuild_read_failure:1; 59887011Smsmith u_int8_t rebuild_write_failure:1; 59987011Smsmith u_int8_t res3:6; 60087011Smsmith u_int8_t drive_failure_map[CISS_BIG_MAP_ENTRIES / 8]; 60187011Smsmith u_int16_t remap_count[CISS_BIG_MAP_ENTRIES]; 60287011Smsmith u_int8_t replacement_map[CISS_BIG_MAP_ENTRIES / 8]; 60387011Smsmith u_int8_t active_spare_map[CISS_BIG_MAP_ENTRIES / 8]; 60487011Smsmith u_int8_t spare_to_replace_map[CISS_BIG_MAP_ENTRIES]; 60587011Smsmith u_int8_t replaced_marked_ok_map[CISS_BIG_MAP_ENTRIES / 8]; 60687011Smsmith u_int8_t drive_rebuilding; 607130129Sps u_int64_t big_blocks_to_recover; 608130129Sps u_int8_t res4[28]; 609103870Salfred} __packed; 61087011Smsmith 61187011Smsmith/* CISS_BMIC_ID_CTLR */ 61287011Smsmithstruct ciss_bmic_id_table { 61387011Smsmith u_int8_t configured_logical_drives; 61487011Smsmith u_int32_t config_signature; 61587011Smsmith char running_firmware_revision[4]; 61687011Smsmith char stored_firmware_revision[4]; 61787011Smsmith u_int8_t hardware_revision; 618268018Ssbruno u_int8_t boot_block_revision[4]; 61987011Smsmith u_int32_t deprecated_drive_present_map; 62087011Smsmith u_int32_t deprecated_external_drive_present_map; 62187011Smsmith u_int32_t board_id; 622268018Ssbruno u_int8_t swapped_error_cable; 62387011Smsmith u_int32_t deprecated_non_disk_map; 624268018Ssbruno u_int8_t bad_host_ram_addr; 625268018Ssbruno u_int8_t cpu_revision; 626268018Ssbruno u_int8_t res3[3]; 62787011Smsmith char marketting_revision; 628268018Ssbruno u_int8_t controller_flags; 629268018Ssbruno#define CONTROLLER_FLAGS_FLASH_ROM_INSTALLED 0x01 630268018Ssbruno#define CONTROLLER_FLAGS_DIAGS_MODE_BIT 0x02 631268018Ssbruno#define CONTROLLER_FLAGS_EXPAND_32MB_FX 0x04 632268018Ssbruno#define CONTROLLER_FLAGS_MORE_THAN_7_SUPPORT 0x08 633268018Ssbruno#define CONTROLLER_FLAGS_DAISY_SUPPORT_BIT 0x10 634268018Ssbruno#define CONTROLLER_FLAGS_RES6 0x20 635268018Ssbruno#define CONTROLLER_FLAGS_RES7 0x40 636268018Ssbruno#define CONTROLLER_FLAGS_BIG_MAP_SUPPORT 0x80 637268018Ssbruno u_int8_t host_flags; 638268018Ssbruno#define HOST_FLAGS_SDB_ASIC_WORK_AROUND 0x01 639268018Ssbruno#define HOST_FLAGS_PCI_DATA_BUS_PARITY_SUPPORT 0x02 640268018Ssbruno#define HOST_FLAGS_RES3 0x04 641268018Ssbruno#define HOST_FLAGS_RES4 0x08 642268018Ssbruno#define HOST_FLAGS_RES5 0x10 643268018Ssbruno#define HOST_FLAGS_RES6 0x20 644268018Ssbruno#define HOST_FLAGS_RES7 0x30 645268018Ssbruno#define HOST_FLAGS_RES8 0x40 646268018Ssbruno u_int8_t expand_disable_code; 647268018Ssbruno#define EXPAND_DISABLE_NOT_NEEDED 0x01 648268018Ssbruno#define EXPAND_DISABLE_MISSING_CACHE_BOARD 0x02 649268018Ssbruno#define EXPAND_DISABLE_WCXC_FATAL_CACHE_BITS 0x04 650268018Ssbruno#define EXPAND_DISABLE_CACHE_PERM_DISABLED 0x08 651268018Ssbruno#define EXPAND_DISABLE_RAM_ALLOCATION_FAILED 0x10 652268018Ssbruno#define EXPAND_DISABLE_BATTEREIS_DISCHARGED 0x20 653268018Ssbruno#define EXPAND_DISABLE_RES7 0x40 654268018Ssbruno#define EXPAND_DISABLE_REBUILD_RUNNING 0x80 655268018Ssbruno u_int8_t scsi_chip_count; 656268018Ssbruno u_int32_t maximum_blocks; 65787011Smsmith u_int32_t controller_clock; 65887011Smsmith u_int8_t drives_per_scsi_bus; 65987011Smsmith u_int8_t big_drive_present_map[CISS_BIG_MAP_ENTRIES / 8]; 66087011Smsmith u_int8_t big_external_drive_present_map[CISS_BIG_MAP_ENTRIES / 8]; 66187011Smsmith u_int8_t big_non_disk_map[CISS_BIG_MAP_ENTRIES / 8]; 662268018Ssbruno 663268018Ssbruno u_int16_t task_flags; /* used for FW debugging */ 664268018Ssbruno u_int8_t ICL_bus_map; /* Bitmap used for ICL between controllers */ 665268018Ssbruno u_int8_t redund_ctlr_modes_support; /* See REDUNDANT MODE VALUES */ 666268018Ssbruno u_int8_t curr_redund_ctlr_mode; 667268018Ssbruno u_int8_t redund_ctlr_status; 668268018Ssbruno u_int8_t redund_op_failure_code; 669268018Ssbruno 670268018Ssbruno u_int8_t unsupported_nile_bus; 671268018Ssbruno u_int8_t host_i2c_autorev; 672268018Ssbruno u_int8_t cpld_revision; 673268018Ssbruno u_int8_t fibre_chip_count; 674268018Ssbruno u_int8_t daughterboard_type; 675268018Ssbruno u_int8_t more_swapped_config_cable_error; 676268018Ssbruno 677268018Ssbruno u_int8_t license_key_status; 678268018Ssbruno u_int8_t access_module_status; 679268018Ssbruno u_int8_t features_supported[12]; 680268018Ssbruno u_int8_t rec_rom_inact_rev[4]; /* Recovery ROM inactive f/w revision */ 681268018Ssbruno u_int8_t rec_rom_act_status; /* Recovery ROM flags */ 682268018Ssbruno u_int8_t pci_to_pci_status; /* PCI to PCI bridge status */ 683268018Ssbruno u_int32_t redundant_server_info; /* Reserved for future use */ 684268018Ssbruno u_int8_t percent_write_cache; /* Percent of memory allocated to write cache */ 685268018Ssbruno u_int16_t daughterboard_size_mb; /* Total size (MB) of cache board */ 686268018Ssbruno u_int8_t cache_batter_count; /* Number of cache batteries */ 687268018Ssbruno u_int16_t total_controller_mem_mb; /* Total size (MB) of atttached memory */ 688268018Ssbruno u_int8_t more_controller_flags; /* Additional controller flags byte */ 689268018Ssbruno u_int8_t x_board_host_i2c_rev; /* 2nd byte of 3 byte autorev field */ 690268018Ssbruno u_int8_t battery_pic_rev; /* BBWC PIC revision */ 691268018Ssbruno/* 692268018Ssbruno * Below here I have no documentation on the rest of this data structure. It is 693268018Ssbruno * inferred from the opensource cciss_vol_status application. I assume that this 694268018Ssbruno * data strucutre is 512 bytes in total size, do not exceed it. 695268018Ssbruno */ 696268018Ssbruno u_int8_t bDdffVersion[4]; /* DDFF update engine version */ 697268018Ssbruno u_int16_t usMaxLogicalUnits; /* Maximum logical units supported */ 698268018Ssbruno u_int16_t usExtLogicalUnitCount; /* Big num configured logical units */ 699268018Ssbruno u_int16_t usMaxPhysicalDevices; /* Maximum physical devices supported */ 700268018Ssbruno u_int16_t usMaxPhyDrvPerLogicalUnit; /* Max physical drive per logical unit */ 701268018Ssbruno u_int8_t bEnclosureCount; /* Number of attached enclosures */ 702268018Ssbruno u_int8_t bExpanderCount; /* Number of expanders detected */ 703268018Ssbruno u_int16_t usOffsetToEDPbitmap; /* Offset to extended drive present map*/ 704268018Ssbruno u_int16_t usOffsetToEEDPbitmap; /* Offset to extended external drive present map */ 705268018Ssbruno u_int16_t usOffsetToENDbitmap; /* Offset to extended non-disk map */ 706268018Ssbruno u_int8_t bInternalPortStatus[8]; /* Internal port status bytes */ 707268018Ssbruno u_int8_t bExternalPortStatus[8]; /* External port status bytes */ 708268018Ssbruno u_int32_t uiYetMoreControllerFlags;/* Yet More Controller flags */ 709268018Ssbruno#define YMORE_CONTROLLER_FLAGS_JBOD_SUPPORTED \ 710268018Ssbruno ( 1 << 25 ) /* Controller has JBOD support */ 711268018Ssbruno 712268018Ssbruno u_int8_t bLastLockup; /* Last lockup code */ 713268018Ssbruno u_int8_t bSlot; /* PCI slot according to option ROM*/ 714268018Ssbruno u_int16_t usBuildNum; /* Build number */ 715268018Ssbruno u_int32_t uiMaxSafeFullStripeSize; /* Maximum safe full stripe size */ 716268018Ssbruno u_int32_t uiTotalLength; /* Total structure length */ 717268018Ssbruno u_int8_t bVendorID[8]; /* Vendor ID */ 718268018Ssbruno u_int8_t bProductID[16]; /* Product ID */ 719268018Ssbruno/* 720268018Ssbruno * These are even more obscure as they seem to only be available in cciss_vol_status 721268018Ssbruno */ 722268018Ssbruno u_int32_t ExtendedLastLockupCode; 723268018Ssbruno u_int16_t MaxRaid; 724268018Ssbruno u_int16_t MaxParity; 725268018Ssbruno u_int16_t MaxADGStripSize; 726268018Ssbruno u_int16_t YetMoreSwappedCables; 727268018Ssbruno u_int8_t MaxDevicePaths; 728268018Ssbruno u_int8_t PowerUPNvramFlags; 729268018Ssbruno#define PWR_UP_FLAG_JBOD_ENABLED 0x08 /*JBOD mode is enabled, all RAID features off */ 730268018Ssbruno 731268018Ssbruno u_int16_t ZonedOffset; 732268018Ssbruno u_int32_t FixedFieldsLength; 733268018Ssbruno u_int8_t FWCompileTimeStamp[24]; 734268018Ssbruno u_int32_t EvenMoreControllerFlags; 735268018Ssbruno u_int8_t padding[240]; 736103870Salfred} __packed; 73787011Smsmith 73887011Smsmith/* CISS_BMIC_ID_PDRIVE */ 73987011Smsmithstruct ciss_bmic_id_pdrive { 74087011Smsmith u_int8_t scsi_bus; 74187011Smsmith u_int8_t scsi_id; 74287011Smsmith u_int16_t block_size; 74387011Smsmith u_int32_t total_blocks; 74487011Smsmith u_int32_t reserved_blocks; 74587011Smsmith char model[40]; 74687011Smsmith char serial[40]; 74787011Smsmith char revision[8]; 74887011Smsmith u_int8_t inquiry_bits; 74987011Smsmith u_int8_t res1[2]; 75087011Smsmith u_int8_t drive_present:1; 75187011Smsmith u_int8_t non_disk:1; 75287011Smsmith u_int8_t wide:1; 75387011Smsmith u_int8_t synchronous:1; 75487011Smsmith u_int8_t narrow:1; 75587011Smsmith u_int8_t wide_downgraded_to_narrow:1; 75687011Smsmith u_int8_t ultra:1; 75787011Smsmith u_int8_t ultra2:1; 75887011Smsmith u_int8_t SMART:1; 75987011Smsmith u_int8_t SMART_errors_recorded:1; 76087011Smsmith u_int8_t SMART_errors_enabled:1; 76187011Smsmith u_int8_t SMART_errors_detected:1; 76287011Smsmith u_int8_t external:1; 76387011Smsmith u_int8_t configured:1; 76487011Smsmith u_int8_t configured_spare:1; 76587011Smsmith u_int8_t cache_saved_enabled:1; 76687011Smsmith u_int8_t res2; 76787011Smsmith u_int8_t res3:6; 76887011Smsmith u_int8_t cache_currently_enabled:1; 76987011Smsmith u_int8_t cache_safe:1; 77087011Smsmith u_int8_t res4[5]; 77187011Smsmith char connector[2]; 77287011Smsmith u_int8_t res5; 77387011Smsmith u_int8_t bay; 774128545Sps u_int16_t rpm; 775128545Sps u_int8_t drive_type; 776128545Sps u_int8_t res6[393]; 777103870Salfred} __packed; 77887011Smsmith 77987011Smsmith/* CISS_BMIC_BLINK_PDRIVE */ 78087011Smsmith/* CISS_BMIC_SENSE_BLINK_PDRIVE */ 78187011Smsmithstruct ciss_bmic_blink_pdrive { 78287011Smsmith u_int32_t blink_duration; /* 10ths of a second */ 78387011Smsmith u_int32_t duration_elapsed; /* only for sense command */ 78487011Smsmith u_int8_t blinktab[256]; 78587011Smsmith#define CISS_BMIC_BLINK_ALL 1 78687011Smsmith#define CISS_BMIC_BLINK_TIMED 2 78787011Smsmith u_int8_t res2[248]; 788103870Salfred} __packed; 78987011Smsmith 79087011Smsmith/* CISS_BMIC_FLUSH_CACHE */ 79187011Smsmithstruct ciss_bmic_flush_cache { 79287011Smsmith u_int16_t flag; 79387011Smsmith#define CISS_BMIC_FLUSH_AND_ENABLE 0 79487011Smsmith#define CISS_BMIC_FLUSH_AND_DISABLE 1 79587011Smsmith u_int8_t res1[510]; 796103870Salfred} __packed; 79787011Smsmith 79887011Smsmith#ifdef _KERNEL 79987011Smsmith/* 80087011Smsmith * CISS "simple" transport layer. 80187011Smsmith * 80287011Smsmith * Note that there are two slightly different versions of this interface 80387011Smsmith * with different interrupt mask bits. There's nothing like consistency... 80487011Smsmith */ 80587011Smsmith#define CISS_TL_SIMPLE_BAR_REGS 0x10 /* BAR pointing to register space */ 80687011Smsmith#define CISS_TL_SIMPLE_BAR_CFG 0x14 /* BAR pointing to space containing config table */ 80787011Smsmith 80887011Smsmith#define CISS_TL_SIMPLE_IDBR 0x20 /* inbound doorbell register */ 80987011Smsmith#define CISS_TL_SIMPLE_IDBR_CFG_TABLE (1<<0) /* notify controller of config table update */ 81087011Smsmith 81187011Smsmith#define CISS_TL_SIMPLE_ISR 0x30 /* interrupt status register */ 81287011Smsmith#define CISS_TL_SIMPLE_IMR 0x34 /* interrupt mask register */ 81387011Smsmith#define CISS_TL_SIMPLE_INTR_OPQ_SA5 (1<<3) /* OPQ not empty interrupt, SA5 boards */ 81487011Smsmith#define CISS_TL_SIMPLE_INTR_OPQ_SA5B (1<<2) /* OPQ not empty interrupt, SA5B boards */ 81587011Smsmith 81687011Smsmith#define CISS_TL_SIMPLE_IPQ 0x40 /* inbound post queue */ 81787011Smsmith#define CISS_TL_SIMPLE_OPQ 0x44 /* outbound post queue */ 81887011Smsmith#define CISS_TL_SIMPLE_OPQ_EMPTY (~(u_int32_t)0) 81987011Smsmith 820180454Sscottl#define CISS_TL_SIMPLE_OSR 0x9c /* outbound status register */ 821180454Sscottl#define CISS_TL_SIMPLE_ODC 0xa0 /* outbound doorbell clear register */ 822180454Sscottl#define CISS_TL_SIMPLE_ODC_CLEAR (0x1) 823180454Sscottl 82487011Smsmith#define CISS_TL_SIMPLE_CFG_BAR 0xb4 /* should be 0x14 */ 82587011Smsmith#define CISS_TL_SIMPLE_CFG_OFF 0xb8 /* offset in BAR at which config table is located */ 82687011Smsmith 82787011Smsmith/* 82887011Smsmith * Register access primitives. 82987011Smsmith */ 83087011Smsmith#define CISS_TL_SIMPLE_READ(sc, ofs) \ 83187011Smsmith bus_space_read_4(sc->ciss_regs_btag, sc->ciss_regs_bhandle, ofs) 83287011Smsmith#define CISS_TL_SIMPLE_WRITE(sc, ofs, val) \ 83387011Smsmith bus_space_write_4(sc->ciss_regs_btag, sc->ciss_regs_bhandle, ofs, val) 83487011Smsmith 83587011Smsmith#define CISS_TL_SIMPLE_POST_CMD(sc, phys) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IPQ, phys) 83687011Smsmith#define CISS_TL_SIMPLE_FETCH_CMD(sc) CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_OPQ) 83787011Smsmith 838182422Sscottl#define CISS_TL_PERF_INTR_OPQ (CISS_TL_SIMPLE_INTR_OPQ_SA5 | CISS_TL_SIMPLE_INTR_OPQ_SA5B) 839182422Sscottl#define CISS_TL_PERF_INTR_MSI 0x01 840182422Sscottl 841197263Sscottl#define CISS_TL_PERF_POST_CMD(sc, cr) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IPQ, cr->cr_ccphys | (cr)->cr_sg_tag) 842180454Sscottl#define CISS_TL_PERF_FLUSH_INT(sc) CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_OSR) 843180454Sscottl#define CISS_TL_PERF_CLEAR_INT(sc) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_ODC, CISS_TL_SIMPLE_ODC_CLEAR) 844180454Sscottl#define CISS_CYCLE_MASK 0x00000001 845180454Sscottl 846197261Sscottl/* Only need one MSI/MSI-X vector */ 847197261Sscottl#define CISS_MSI_COUNT 1 848180454Sscottl 849182422Sscottl#define CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc) \ 850182422Sscottl CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IMR, \ 851182422Sscottl CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IMR) | (sc)->ciss_interrupt_mask) 852182422Sscottl#define CISS_TL_SIMPLE_ENABLE_INTERRUPTS(sc) \ 853182422Sscottl CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IMR, \ 854182422Sscottl CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IMR) & ~(sc)->ciss_interrupt_mask) 85587011Smsmith 856182422Sscottl 857197263Sscottl 85887011Smsmith#endif /* _KERNEL */ 859