1*7b13bc96SSascha Wildner /*- 2*7b13bc96SSascha Wildner * Copyright (c) 2018 VMware, Inc. 3*7b13bc96SSascha Wildner * 4*7b13bc96SSascha Wildner * SPDX-License-Identifier: (BSD-2-Clause OR GPL-2.0) 5*7b13bc96SSascha Wildner * 6*7b13bc96SSascha Wildner * $FreeBSD$ 7*7b13bc96SSascha Wildner */ 8*7b13bc96SSascha Wildner 9*7b13bc96SSascha Wildner #ifndef _PVSCSI_H_ 10*7b13bc96SSascha Wildner #define _PVSCSI_H_ 11*7b13bc96SSascha Wildner 12*7b13bc96SSascha Wildner #define MASK(v) ((1 << (v)) - 1) 13*7b13bc96SSascha Wildner 14*7b13bc96SSascha Wildner #define PCI_VENDOR_ID_VMWARE 0x15ad 15*7b13bc96SSascha Wildner #define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07c0 16*7b13bc96SSascha Wildner 17*7b13bc96SSascha Wildner enum pvscsi_reg_offset { 18*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_COMMAND = 0x0000, 19*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_COMMAND_DATA = 0x0004, 20*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_COMMAND_STATUS = 0x0008, 21*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_LAST_STS_0 = 0x0100, 22*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_LAST_STS_1 = 0x0104, 23*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_LAST_STS_2 = 0x0108, 24*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_LAST_STS_3 = 0x010c, 25*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_INTR_STATUS = 0x100c, 26*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_INTR_MASK = 0x2010, 27*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_KICK_NON_RW_IO = 0x3014, 28*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_DEBUG = 0x3018, 29*7b13bc96SSascha Wildner PVSCSI_REG_OFFSET_KICK_RW_IO = 0x4018, 30*7b13bc96SSascha Wildner }; 31*7b13bc96SSascha Wildner 32*7b13bc96SSascha Wildner enum pvscsi_commands { 33*7b13bc96SSascha Wildner PVSCSI_CMD_FIRST = 0, 34*7b13bc96SSascha Wildner 35*7b13bc96SSascha Wildner PVSCSI_CMD_ADAPTER_RESET = 1, 36*7b13bc96SSascha Wildner PVSCSI_CMD_ISSUE_SCSI = 2, 37*7b13bc96SSascha Wildner PVSCSI_CMD_SETUP_RINGS = 3, 38*7b13bc96SSascha Wildner PVSCSI_CMD_RESET_BUS = 4, 39*7b13bc96SSascha Wildner PVSCSI_CMD_RESET_DEVICE = 5, 40*7b13bc96SSascha Wildner PVSCSI_CMD_ABORT_CMD = 6, 41*7b13bc96SSascha Wildner PVSCSI_CMD_CONFIG = 7, 42*7b13bc96SSascha Wildner PVSCSI_CMD_SETUP_MSG_RING = 8, 43*7b13bc96SSascha Wildner PVSCSI_CMD_DEVICE_UNPLUG = 9, 44*7b13bc96SSascha Wildner PVSCSI_CMD_SETUP_REQCALLTHRESHOLD = 10, 45*7b13bc96SSascha Wildner PVSCSI_CMD_GET_MAX_TARGETS = 11, 46*7b13bc96SSascha Wildner 47*7b13bc96SSascha Wildner PVSCSI_CMD_LAST = 12, 48*7b13bc96SSascha Wildner }; 49*7b13bc96SSascha Wildner 50*7b13bc96SSascha Wildner struct pvscsi_cmd_desc_reset_device { 51*7b13bc96SSascha Wildner uint32_t target; 52*7b13bc96SSascha Wildner uint8_t lun[8]; 53*7b13bc96SSascha Wildner }; 54*7b13bc96SSascha Wildner 55*7b13bc96SSascha Wildner struct pvscsi_cmd_desc_abort_cmd { 56*7b13bc96SSascha Wildner uint64_t context; 57*7b13bc96SSascha Wildner uint32_t target; 58*7b13bc96SSascha Wildner uint32_t pad; 59*7b13bc96SSascha Wildner }; 60*7b13bc96SSascha Wildner 61*7b13bc96SSascha Wildner #define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 32 62*7b13bc96SSascha Wildner #define PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES 16 63*7b13bc96SSascha Wildner 64*7b13bc96SSascha Wildner struct pvscsi_cmd_desc_setup_rings { 65*7b13bc96SSascha Wildner uint32_t req_ring_num_pages; 66*7b13bc96SSascha Wildner uint32_t cmp_ring_num_pages; 67*7b13bc96SSascha Wildner uint64_t rings_state_ppn; 68*7b13bc96SSascha Wildner uint64_t req_ring_ppns[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES]; 69*7b13bc96SSascha Wildner uint64_t cmp_ring_ppns[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES]; 70*7b13bc96SSascha Wildner }; 71*7b13bc96SSascha Wildner 72*7b13bc96SSascha Wildner struct pvscsi_cmd_desc_setup_msg_ring { 73*7b13bc96SSascha Wildner uint32_t num_pages; 74*7b13bc96SSascha Wildner uint32_t pad_; 75*7b13bc96SSascha Wildner uint64_t ring_ppns[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES]; 76*7b13bc96SSascha Wildner }; 77*7b13bc96SSascha Wildner 78*7b13bc96SSascha Wildner struct pvscsi_rings_state { 79*7b13bc96SSascha Wildner uint32_t req_prod_idx; 80*7b13bc96SSascha Wildner uint32_t req_cons_idx; 81*7b13bc96SSascha Wildner uint32_t req_num_entries_log2; 82*7b13bc96SSascha Wildner uint32_t cmp_prod_idx; 83*7b13bc96SSascha Wildner uint32_t cmp_cons_idx; 84*7b13bc96SSascha Wildner uint32_t cmp_num_entries_log2; 85*7b13bc96SSascha Wildner uint32_t req_call_threshold; 86*7b13bc96SSascha Wildner uint8_t _pad[100]; 87*7b13bc96SSascha Wildner uint32_t msg_prod_idx; 88*7b13bc96SSascha Wildner uint32_t msg_cons_idx; 89*7b13bc96SSascha Wildner uint32_t msg_num_entries_log2; 90*7b13bc96SSascha Wildner }; 91*7b13bc96SSascha Wildner 92*7b13bc96SSascha Wildner #define PVSCSI_FLAG_CMD_WITH_SG_LIST (1 << 0) 93*7b13bc96SSascha Wildner #define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB (1 << 1) 94*7b13bc96SSascha Wildner #define PVSCSI_FLAG_CMD_DIR_NONE (1 << 2) 95*7b13bc96SSascha Wildner #define PVSCSI_FLAG_CMD_DIR_TOHOST (1 << 3) 96*7b13bc96SSascha Wildner #define PVSCSI_FLAG_CMD_DIR_TODEVICE (1 << 4) 97*7b13bc96SSascha Wildner 98*7b13bc96SSascha Wildner #define PVSCSI_FLAG_RESERVED_MASK (~MASK(5)) 99*7b13bc96SSascha Wildner 100*7b13bc96SSascha Wildner #define PVSCSI_INTR_CMPL_0 (1 << 0) 101*7b13bc96SSascha Wildner #define PVSCSI_INTR_CMPL_1 (1 << 1) 102*7b13bc96SSascha Wildner #define PVSCSI_INTR_CMPL_MASK MASK(2) 103*7b13bc96SSascha Wildner 104*7b13bc96SSascha Wildner #define PVSCSI_INTR_MSG_0 (1 << 2) 105*7b13bc96SSascha Wildner #define PVSCSI_INTR_MSG_1 (1 << 3) 106*7b13bc96SSascha Wildner #define PVSCSI_INTR_MSG_MASK (MASK(2) << 2) 107*7b13bc96SSascha Wildner 108*7b13bc96SSascha Wildner #define PVSCSI_INTR_ALL_SUPPORTED MASK(4) 109*7b13bc96SSascha Wildner 110*7b13bc96SSascha Wildner struct pvscsi_ring_req_desc { 111*7b13bc96SSascha Wildner uint64_t context; 112*7b13bc96SSascha Wildner uint64_t data_addr; 113*7b13bc96SSascha Wildner uint64_t data_len; 114*7b13bc96SSascha Wildner uint64_t sense_addr; 115*7b13bc96SSascha Wildner uint32_t sense_len; 116*7b13bc96SSascha Wildner uint32_t flags; 117*7b13bc96SSascha Wildner uint8_t cdb[16]; 118*7b13bc96SSascha Wildner uint8_t cdb_len; 119*7b13bc96SSascha Wildner uint8_t lun[8]; 120*7b13bc96SSascha Wildner uint8_t tag; 121*7b13bc96SSascha Wildner uint8_t bus; 122*7b13bc96SSascha Wildner uint8_t target; 123*7b13bc96SSascha Wildner uint16_t vcpu_hint; 124*7b13bc96SSascha Wildner uint8_t unused[58]; 125*7b13bc96SSascha Wildner }; 126*7b13bc96SSascha Wildner 127*7b13bc96SSascha Wildner struct pvscsi_ring_cmp_desc { 128*7b13bc96SSascha Wildner uint64_t context; 129*7b13bc96SSascha Wildner uint64_t data_len; 130*7b13bc96SSascha Wildner uint32_t sense_len; 131*7b13bc96SSascha Wildner uint16_t host_status; 132*7b13bc96SSascha Wildner uint16_t scsi_status; 133*7b13bc96SSascha Wildner uint32_t _pad[2]; 134*7b13bc96SSascha Wildner }; 135*7b13bc96SSascha Wildner 136*7b13bc96SSascha Wildner #define PVSCSI_MAX_SG_ENTRIES_PER_SEGMENT 128 137*7b13bc96SSascha Wildner #define PVSCSI_MAX_NUM_SG_SEGMENTS 128 138*7b13bc96SSascha Wildner #define PVSCSI_SGE_FLAG_CHAIN_ELEMENT (1 << 0) 139*7b13bc96SSascha Wildner 140*7b13bc96SSascha Wildner struct pvscsi_sg_element { 141*7b13bc96SSascha Wildner uint64_t addr; 142*7b13bc96SSascha Wildner uint32_t length; 143*7b13bc96SSascha Wildner uint32_t flags; 144*7b13bc96SSascha Wildner }; 145*7b13bc96SSascha Wildner 146*7b13bc96SSascha Wildner enum pvscsi_msg_type { 147*7b13bc96SSascha Wildner PVSCSI_MSG_DEV_ADDED = 0, 148*7b13bc96SSascha Wildner PVSCSI_MSG_DEV_REMOVED = 1, 149*7b13bc96SSascha Wildner PVSCSI_MSG_LAST = 2, 150*7b13bc96SSascha Wildner }; 151*7b13bc96SSascha Wildner 152*7b13bc96SSascha Wildner struct pvscsi_ring_msg_desc { 153*7b13bc96SSascha Wildner uint32_t type; 154*7b13bc96SSascha Wildner uint32_t args[31]; 155*7b13bc96SSascha Wildner }; 156*7b13bc96SSascha Wildner 157*7b13bc96SSascha Wildner struct pvscsi_ring_msg_dev_status_changed { 158*7b13bc96SSascha Wildner uint32_t type; 159*7b13bc96SSascha Wildner uint32_t bus; 160*7b13bc96SSascha Wildner uint32_t target; 161*7b13bc96SSascha Wildner uint8_t lun[8]; 162*7b13bc96SSascha Wildner uint32_t pad[27]; 163*7b13bc96SSascha Wildner }; 164*7b13bc96SSascha Wildner 165*7b13bc96SSascha Wildner struct pvscsi_cmd_desc_setup_req_call { 166*7b13bc96SSascha Wildner uint32_t enable; 167*7b13bc96SSascha Wildner }; 168*7b13bc96SSascha Wildner 169*7b13bc96SSascha Wildner #define PVSCSI_MAX_NUM_PAGES_REQ_RING PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 170*7b13bc96SSascha Wildner #define PVSCSI_MAX_NUM_PAGES_CMP_RING PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 171*7b13bc96SSascha Wildner #define PVSCSI_MAX_NUM_PAGES_MSG_RING PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES 172*7b13bc96SSascha Wildner 173*7b13bc96SSascha Wildner #define PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \ 174*7b13bc96SSascha Wildner (PAGE_SIZE / sizeof(struct pvscsi_ring_req_desc)) 175*7b13bc96SSascha Wildner #define PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE \ 176*7b13bc96SSascha Wildner (PAGE_SIZE / sizeof(struct pvscs_ring_cmp_desc)) 177*7b13bc96SSascha Wildner #define PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE \ 178*7b13bc96SSascha Wildner (PAGE_SIZE / sizeof(struct pvscsi_ring_msg_desc)) 179*7b13bc96SSascha Wildner 180*7b13bc96SSascha Wildner #define PVSCSI_MAX_REQ_QUEUE_DEPTH \ 181*7b13bc96SSascha Wildner (PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE) 182*7b13bc96SSascha Wildner #define PVSCSI_MAX_CMP_QUEUE_DEPTH \ 183*7b13bc96SSascha Wildner (PVSCSI_MAX_NUM_PAGES_CMP_RING * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE) 184*7b13bc96SSascha Wildner #define PVSCSI_MAX_QUEUE_DEPTH \ 185*7b13bc96SSascha Wildner MAX(PVSCSI_MAX_REQ_QUEUE_DEPTH, PVSCSI_MAX_CMP_QUEUE_DEPTH) 186*7b13bc96SSascha Wildner 187*7b13bc96SSascha Wildner enum pvscsi_host_status { 188*7b13bc96SSascha Wildner BTSTAT_SUCCESS = 0x00, 189*7b13bc96SSascha Wildner BTSTAT_LINKED_COMMAND_COMPLETED = 0x0a, 190*7b13bc96SSascha Wildner BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b, 191*7b13bc96SSascha Wildner BTSTAT_DATA_UNDERRUN = 0x0c, 192*7b13bc96SSascha Wildner BTSTAT_SELTIMEO = 0x11, 193*7b13bc96SSascha Wildner BTSTAT_DATARUN = 0x12, 194*7b13bc96SSascha Wildner BTSTAT_BUSFREE = 0x13, 195*7b13bc96SSascha Wildner BTSTAT_INVPHASE = 0x14, 196*7b13bc96SSascha Wildner BTSTAT_INVCODE = 0x15, 197*7b13bc96SSascha Wildner BTSTAT_INVOPCODE = 0x16, 198*7b13bc96SSascha Wildner BTSTAT_LUNMISMATCH = 0x17, 199*7b13bc96SSascha Wildner BTSTAT_INVPARAM = 0x1a, 200*7b13bc96SSascha Wildner BTSTAT_SENSFAILED = 0x1b, 201*7b13bc96SSascha Wildner BTSTAT_TAGREJECT = 0x1c, 202*7b13bc96SSascha Wildner BTSTAT_BADMSG = 0x1d, 203*7b13bc96SSascha Wildner BTSTAT_HAHARDWARE = 0x20, 204*7b13bc96SSascha Wildner BTSTAT_NORESPONSE = 0x21, 205*7b13bc96SSascha Wildner BTSTAT_SENTRST = 0x22, 206*7b13bc96SSascha Wildner BTSTAT_RECVRST = 0x23, 207*7b13bc96SSascha Wildner BTSTAT_DISCONNECT = 0x24, 208*7b13bc96SSascha Wildner BTSTAT_BUSRESET = 0x25, 209*7b13bc96SSascha Wildner BTSTAT_ABORTQUEUE = 0x26, 210*7b13bc96SSascha Wildner BTSTAT_HASOFTWARE = 0x27, 211*7b13bc96SSascha Wildner BTSTAT_HATIMEOUT = 0x30, 212*7b13bc96SSascha Wildner BTSTAT_SCSIPARITY = 0x34, 213*7b13bc96SSascha Wildner }; 214*7b13bc96SSascha Wildner 215*7b13bc96SSascha Wildner #endif /* !_PVSCSI_H_ */ 216