diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-03-05 23:10:43 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-03-05 23:10:43 +0000 |
commit | 2638bfb9ba68f4b496b22446baadc84b5e957404 (patch) | |
tree | 8c6f69cd41611c7c6b6dedf486f1f880dc954114 /sys/dev/ic/qlwreg.h | |
parent | 7b83993f03185ffa08efce430b09e06de7dff575 (diff) |
Introduce qlw(4), a new driver for QLogic ISP SCSI HBAs. For now only
supports the PCI variants; SBUs support will follow. Works reasonably
well now. Others are encouraged to test it.
Diffstat (limited to 'sys/dev/ic/qlwreg.h')
-rw-r--r-- | sys/dev/ic/qlwreg.h | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/sys/dev/ic/qlwreg.h b/sys/dev/ic/qlwreg.h new file mode 100644 index 00000000000..d584d7fc2d4 --- /dev/null +++ b/sys/dev/ic/qlwreg.h @@ -0,0 +1,307 @@ +/* $OpenBSD: qlwreg.h,v 1.1 2014/03/05 23:10:41 kettenis Exp $ */ + +/* + * Copyright (c) 2013, 2014 Jonathan Matthew <jmatthew@openbsd.org> + * Copyright (c) 2014 Mark Kettenis <kettenis@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* firmware loading */ +#define QLW_CODE_ORG 0x1000 + +/* interrupt types */ +#define QLW_INT_TYPE_MBOX 1 +#define QLW_INT_TYPE_ASYNC 2 +#define QLW_INT_TYPE_IO 3 +#define QLW_INT_TYPE_OTHER 4 + +/* ISP registers */ +#define QLW_CFG0 0x04 +#define QLW_CFG1 0x06 +#define QLW_INT_CTRL 0x08 +#define QLW_INT_STATUS 0x0a +#define QLW_SEMA 0x0c +#define QLW_NVRAM 0x0e +#define QLW_FLASH_BIOS_DATA 0x10 +#define QLW_FLASH_BIOS_ADDR 0x12 +#define QLW_MBOX_BASE 0x70 +#define QLW_HOST_CMD_CTRL 0xc0 +#define QLW_GPIO_DATA 0xcc +#define QLW_GPIO_ENABLE 0xce + +#define QLW_REQ_IN QLW_MBOX_BASE + 0x8 +#define QLW_REQ_OUT QLW_MBOX_BASE + 0x8 +#define QLW_RESP_IN QLW_MBOX_BASE + 0xa +#define QLW_RESP_OUT QLW_MBOX_BASE + 0xa + +/* QLW_INT_CTRL */ +#define QLW_RESET 0x0001 + +/* QLW_INT_STATUS */ +#define QLW_INT_REQ 0x0002 +#define QLW_RISC_INT_REQ 0x0004 + +/* QLW_SEMA */ +#define QLW_SEMA_STATUS 0x0002 +#define QLW_SEMA_LOCK 0x0001 + +/* QLW_NVRAM */ +#define QLW_NVRAM_DATA_IN 0x0008 +#define QLW_NVRAM_DATA_OUT 0x0004 +#define QLW_NVRAM_CHIP_SEL 0x0002 +#define QLW_NVRAM_CLOCK 0x0001 +#define QLW_NVRAM_CMD_READ 6 + +/* QLW_HOST_CMD_CTRL write */ +#define QLW_HOST_CMD_SHIFT 12 +#define QLW_HOST_CMD_NOP 0x0 +#define QLW_HOST_CMD_RESET 0x1 +#define QLW_HOST_CMD_PAUSE 0x2 +#define QLW_HOST_CMD_RELEASE 0x3 +#define QLW_HOST_CMD_MASK_PARITY 0x4 +#define QLW_HOST_CMD_SET_HOST_INT 0x5 +#define QLW_HOST_CMD_CLR_HOST_INT 0x6 +#define QLW_HOST_CMD_CLR_RISC_INT 0x7 +#define QLW_HOST_CMD_BIOS 0x9 +#define QLW_HOST_CMD_ENABLE_PARITY 0xa +#define QLW_HOST_CMD_PARITY_ERROR 0xe + +/* QLA_HOST_CMD_CTRL read */ +#define QLA_HOST_STATUS_HOST_INT 0x0080 +#define QLA_HOST_STATUS_RISC_RESET 0x0040 +#define QLA_HOST_STATUS_RISC_PAUSE 0x0020 +#define QLA_HOST_STATUS_RISC_EXT 0x0010 + +/* QLW_MBIX_BASE (reg 0) read */ +#define QLW_MBOX_HAS_STATUS 0x4000 +#define QLW_MBOX_COMPLETE 0x4000 +#define QLW_MBOX_INVALID 0x4001 +#define QLW_ASYNC_BUS_RESET 0x8001 +#define QLW_ASYNC_SYSTEM_ERROR 0x8002 +#define QLW_ASYNC_REQ_XFER_ERROR 0x8003 +#define QLW_ASYNC_RSP_XFER_ERROR 0x8004 +#define QLW_ASYNC_SCSI_CMD_COMPLETE 0x8020 +#define QLW_ASYNC_CTIO_COMPLETE 0x8021 + +/* QLW_MBOX_BASE (reg 0) write */ +#define QLW_MBOX_NOP 0x0000 +#define QLW_MBOX_LOAD_RAM 0x0001 +#define QLW_MBOX_EXEC_FIRMWARE 0x0002 +#define QLW_MBOX_WRITE_RAM_WORD 0x0004 +#define QLW_MBOX_REGISTER_TEST 0x0006 +#define QLW_MBOX_VERIFY_CSUM 0x0007 +#define QLW_MBOX_ABOUT_FIRMWARE 0x0008 +#define QLW_MBOX_BUS_RESET 0x0018 +#define QLW_MBOX_GET_FIRMWARE_STATUS 0x001F +#define QLW_MBOX_SET_INITIATOR_ID 0x0030 +#define QLW_MBOX_SET_SELECTION_TIMEOUT 0x0031 +#define QLW_MBOX_SET_RETRY_COUNT 0x0032 +#define QLW_MBOX_SET_TAG_AGE_LIMIT 0x0033 +#define QLW_MBOX_SET_CLOCK_RATE 0x0034 +#define QLW_MBOX_SET_ACTIVE_NEGATION 0x0035 +#define QLW_MBOX_SET_ASYNC_DATA_SETUP 0x0036 +#define QLW_MBOX_SET_PCI_CONTROL 0x0037 +#define QLW_MBOX_SET_TARGET_PARAMETERS 0x0038 +#define QLW_MBOX_SET_DEVICE_QUEUE 0x0039 +#define QLW_MBOX_SET_SYSTEM_PARAMETER 0x0045 +#define QLW_MBOX_SET_FIRMWARE_FEATURES 0x004a +#define QLW_MBOX_INIT_REQ_QUEUE_A64 0x0052 +#define QLW_MBOX_INIT_RSP_QUEUE_A64 0x0053 +#define QLW_MBOX_SET_DATA_OVERRUN_RECOVERY 0x005a + +/* mailbox operation register bitfields */ +#define QLW_MBOX_ABOUT_FIRMWARE_IN 0x0001 +#define QLW_MBOX_ABOUT_FIRMWARE_OUT 0x004f +#define QLW_MBOX_INIT_FIRMWARE_IN 0x00fd + +/* nvram layout */ +struct qlw_nvram_target { + u_int8_t parameter; + u_int8_t execution_throttle; + u_int8_t sync_period; + u_int8_t flags; + u_int8_t reserved[2]; +} __packed; + +struct qlw_nvram_1040 { + u_int8_t id[4]; + u_int8_t nvram_version; + u_int8_t config1; + u_int8_t reset_delay; + u_int8_t retry_count; + u_int8_t retry_delay; + u_int8_t config2; + u_int8_t tag_age_limit; + u_int8_t flags1; + u_int16_t selection_timeout; + u_int16_t max_queue_depth; + u_int8_t flags2; + u_int8_t reserved_0[5]; + u_int8_t flags3; + u_int8_t reserved_1[5]; + struct qlw_nvram_target target[16]; + u_int8_t reserved_2[3]; + u_int8_t checksum; +} __packed; + +struct qlw_nvram_bus { + u_int8_t config1; + u_int8_t reset_delay; + u_int8_t retry_count; + u_int8_t retry_delay; + u_int8_t config2; + u_int8_t reserved_0; + u_int16_t selection_timeout; + u_int16_t max_queue_depth; + u_int8_t reserved_1[6]; + struct qlw_nvram_target target[16]; +} __packed; + +struct qlw_nvram_1080 { + u_int8_t id[4]; + u_int8_t nvram_version; + u_int8_t flags1; + u_int16_t flags2; + u_int8_t reserved_0[8]; + u_int8_t isp_config; + u_int8_t termination; + u_int16_t isp_parameter; + u_int16_t fw_options; + u_int16_t reserved_1; + struct qlw_nvram_bus bus[2]; + u_int8_t reserved_2[2]; + u_int16_t subsystem_vendor_id; + u_int16_t subsystem_device_id; + u_int8_t reserved_3; + u_int8_t checksum; +} __packed; + +struct qlw_nvram { + u_int8_t id[4]; + u_int8_t nvram_version; + u_int8_t data[251]; +}; + +#define QLW_TARGET_PPR 0x0020 +#define QLW_TARGET_ASYNC 0x0040 +#define QLW_TARGET_NARROW 0x0080 +#define QLW_TARGET_RENEG 0x0100 +#define QLW_TARGET_QFRZ 0x0200 +#define QLW_TARGET_ARQ 0x0400 +#define QLW_TARGET_TAGS 0x0800 +#define QLW_TARGET_SYNC 0x1000 +#define QLW_TARGET_WIDE 0x2000 +#define QLW_TARGET_PARITY 0x4000 +#define QLW_TARGET_DISC 0x8000 +#define QLW_TARGET_SAFE 0xc500 +#define QLW_TARGET_DEFAULT 0xfd00 + +#define QLW_IOCB_CMD_HEAD_OF_QUEUE 0x0002 +#define QLW_IOCB_CMD_ORDERED_QUEUE 0x0004 +#define QLW_IOCB_CMD_SIMPLE_QUEUE 0x0008 +#define QLW_IOCB_CMD_NO_DATA 0x0000 +#define QLW_IOCB_CMD_READ_DATA 0x0020 +#define QLW_IOCB_CMD_WRITE_DATA 0x0040 +#define QLW_IOCB_CMD_NO_FAST_POST 0x0080 + +#define QLW_IOCB_MARKER_SYNC_ALL 2 + +#define QLW_IOCB_SEGS_PER_CMD 4 +#define QLW_IOCB_SEGS_PER_CONT 7 + +struct qlw_iocb_seg { + u_int32_t seg_addr; + u_int32_t seg_len; +} __packed; + +/* IOCB types */ +#define QLW_IOCB_CMD_TYPE_0 0x01 +#define QLW_IOCB_CONT_TYPE_0 0x02 +#define QLW_IOCB_STATUS 0x03 +#define QLW_IOCB_MARKER 0x04 + +struct qlw_iocb_req0 { + u_int8_t entry_type; /* QLW_IOCB_CMD_TYPE_0 */ + u_int8_t entry_count; + u_int8_t seqno; + u_int8_t flags; + + u_int32_t req_handle; + u_int8_t req_lun_trn; + u_int8_t req_target; + u_int16_t req_ccblen; + u_int16_t req_flags; + u_int16_t req_reserved; + u_int16_t req_time; + u_int16_t req_seg_count; + u_int8_t req_cdb[12]; + struct qlw_iocb_seg req0_segs[4]; +} __packed; + +struct qlw_iocb_cont0 { + u_int8_t entry_type; /* QLA_IOCB_CONT_TYPE_0 */ + u_int8_t entry_count; + u_int8_t seqno; + u_int8_t flags; + + u_int32_t reserved; + struct qlw_iocb_seg segs[7]; +} __packed; + +struct qla_iocb_status { + u_int8_t entry_type; /* QLA_IOCB_STATUS */ + u_int8_t entry_count; + u_int8_t seqno; + u_int8_t flags; + + u_int32_t handle; + u_int16_t scsi_status; + u_int16_t completion; + u_int16_t state_flags; + u_int16_t status_flags; + u_int16_t rsp_len; + u_int16_t sense_len; + u_int32_t resid; + u_int8_t fcp_rsp[8]; + u_int8_t sense_data[32]; +} __packed; + +/* completion */ +#define QLW_IOCB_STATUS_COMPLETE 0x0000 +#define QLW_IOCB_STATUS_INCOMPLETE 0x0001 +#define QLW_IOCB_STATUS_DMA_ERROR 0x0002 +#define QLW_IOCB_STATUS_RESET 0x0004 +#define QLW_IOCB_STATUS_ABORTED 0x0005 +#define QLW_IOCB_STATUS_TIMEOUT 0x0006 +#define QLW_IOCB_STATUS_DATA_OVERRUN 0x0007 +#define QLW_IOCB_STATUS_DATA_UNDERRUN 0x0015 +#define QLW_IOCB_STATUS_QUEUE_FULL 0x001C + +#define QLW_STATE_GOT_BUS 0x0100 +#define QLW_STATE_GOT_TARGET 0x0200 + +#define QLW_SCSI_STATUS_SENSE_VALID 0x0200 + +struct qlw_iocb_marker { + u_int8_t entry_type; /* QLW_IOCB_MARKER */ + u_int8_t entry_count; + u_int8_t seqno; + u_int8_t flags; + + u_int32_t handle; + u_int8_t lun; + u_int8_t target; + u_int8_t modifier; + u_int8_t reserved2[53]; +} __packed; |