![]() |
|
|||
0001 /* SPDX-License-Identifier: MIT */ 0002 /****************************************************************************** 0003 * vscsiif.h 0004 * 0005 * Based on the blkif.h code. 0006 * 0007 * Copyright(c) FUJITSU Limited 2008. 0008 */ 0009 0010 #ifndef __XEN__PUBLIC_IO_SCSI_H__ 0011 #define __XEN__PUBLIC_IO_SCSI_H__ 0012 0013 #include "ring.h" 0014 #include "../grant_table.h" 0015 0016 /* 0017 * Feature and Parameter Negotiation 0018 * ================================= 0019 * The two halves of a Xen pvSCSI driver utilize nodes within the XenStore to 0020 * communicate capabilities and to negotiate operating parameters. This 0021 * section enumerates these nodes which reside in the respective front and 0022 * backend portions of the XenStore, following the XenBus convention. 0023 * 0024 * Any specified default value is in effect if the corresponding XenBus node 0025 * is not present in the XenStore. 0026 * 0027 * XenStore nodes in sections marked "PRIVATE" are solely for use by the 0028 * driver side whose XenBus tree contains them. 0029 * 0030 ***************************************************************************** 0031 * Backend XenBus Nodes 0032 ***************************************************************************** 0033 * 0034 *------------------ Backend Device Identification (PRIVATE) ------------------ 0035 * 0036 * p-devname 0037 * Values: string 0038 * 0039 * A free string used to identify the physical device (e.g. a disk name). 0040 * 0041 * p-dev 0042 * Values: string 0043 * 0044 * A string specifying the backend device: either a 4-tuple "h:c:t:l" 0045 * (host, controller, target, lun, all integers), or a WWN (e.g. 0046 * "naa.60014054ac780582:0"). 0047 * 0048 * v-dev 0049 * Values: string 0050 * 0051 * A string specifying the frontend device in form of a 4-tuple "h:c:t:l" 0052 * (host, controller, target, lun, all integers). 0053 * 0054 *--------------------------------- Features --------------------------------- 0055 * 0056 * feature-sg-grant 0057 * Values: unsigned [VSCSIIF_SG_TABLESIZE...65535] 0058 * Default Value: 0 0059 * 0060 * Specifies the maximum number of scatter/gather elements in grant pages 0061 * supported. If not set, the backend supports up to VSCSIIF_SG_TABLESIZE 0062 * SG elements specified directly in the request. 0063 * 0064 ***************************************************************************** 0065 * Frontend XenBus Nodes 0066 ***************************************************************************** 0067 * 0068 *----------------------- Request Transport Parameters ----------------------- 0069 * 0070 * event-channel 0071 * Values: unsigned 0072 * 0073 * The identifier of the Xen event channel used to signal activity 0074 * in the ring buffer. 0075 * 0076 * ring-ref 0077 * Values: unsigned 0078 * 0079 * The Xen grant reference granting permission for the backend to map 0080 * the sole page in a single page sized ring buffer. 0081 * 0082 * protocol 0083 * Values: string (XEN_IO_PROTO_ABI_*) 0084 * Default Value: XEN_IO_PROTO_ABI_NATIVE 0085 * 0086 * The machine ABI rules governing the format of all ring request and 0087 * response structures. 0088 */ 0089 0090 /* 0091 * Xenstore format in practice 0092 * =========================== 0093 * 0094 * The backend driver uses a single_host:many_devices notation to manage domU 0095 * devices. Everything is stored in /local/domain/<backend_domid>/backend/vscsi/. 0096 * The xenstore layout looks like this (dom0 is assumed to be the backend_domid): 0097 * 0098 * <domid>/<vhost>/feature-host = "0" 0099 * <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0" 0100 * <domid>/<vhost>/frontend-id = "<domid>" 0101 * <domid>/<vhost>/online = "1" 0102 * <domid>/<vhost>/state = "4" 0103 * <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1" or "naa.wwn:lun" 0104 * <domid>/<vhost>/vscsi-devs/dev-0/state = "4" 0105 * <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0" 0106 * <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2" 0107 * <domid>/<vhost>/vscsi-devs/dev-1/state = "4" 0108 * <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0" 0109 * 0110 * The frontend driver maintains its state in 0111 * /local/domain/<domid>/device/vscsi/. 0112 * 0113 * <vhost>/backend = "/local/domain/0/backend/vscsi/<domid>/<vhost>" 0114 * <vhost>/backend-id = "0" 0115 * <vhost>/event-channel = "20" 0116 * <vhost>/ring-ref = "43" 0117 * <vhost>/state = "4" 0118 * <vhost>/vscsi-devs/dev-0/state = "4" 0119 * <vhost>/vscsi-devs/dev-1/state = "4" 0120 * 0121 * In addition to the entries for backend and frontend these flags are stored 0122 * for the toolstack: 0123 * 0124 * <domid>/<vhost>/vscsi-devs/dev-1/p-devname = "/dev/$device" 0125 * <domid>/<vhost>/libxl_ctrl_index = "0" 0126 * 0127 * 0128 * Backend/frontend protocol 0129 * ========================= 0130 * 0131 * To create a vhost along with a device: 0132 * <domid>/<vhost>/feature-host = "0" 0133 * <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0" 0134 * <domid>/<vhost>/frontend-id = "<domid>" 0135 * <domid>/<vhost>/online = "1" 0136 * <domid>/<vhost>/state = "1" 0137 * <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1" 0138 * <domid>/<vhost>/vscsi-devs/dev-0/state = "1" 0139 * <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0" 0140 * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-0/state become 4 0141 * 0142 * To add another device to a vhost: 0143 * <domid>/<vhost>/state = "7" 0144 * <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2" 0145 * <domid>/<vhost>/vscsi-devs/dev-1/state = "1" 0146 * <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0" 0147 * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-1/state become 4 0148 * 0149 * To remove a device from a vhost: 0150 * <domid>/<vhost>/state = "7" 0151 * <domid>/<vhost>/vscsi-devs/dev-1/state = "5" 0152 * Wait for <domid>/<vhost>/state to become 4 0153 * Wait for <domid>/<vhost>/vscsi-devs/dev-1/state become 6 0154 * Remove <domid>/<vhost>/vscsi-devs/dev-1/{state,p-dev,v-dev,p-devname} 0155 * Remove <domid>/<vhost>/vscsi-devs/dev-1/ 0156 * 0157 */ 0158 0159 /* Requests from the frontend to the backend */ 0160 0161 /* 0162 * Request a SCSI operation specified via a CDB in vscsiif_request.cmnd. 0163 * The target is specified via channel, id and lun. 0164 * 0165 * The operation to be performed is specified via a CDB in cmnd[], the length 0166 * of the CDB is in cmd_len. sc_data_direction specifies the direction of data 0167 * (to the device, from the device, or none at all). 0168 * 0169 * If data is to be transferred to or from the device the buffer(s) in the 0170 * guest memory is/are specified via one or multiple scsiif_request_segment 0171 * descriptors each specifying a memory page via a grant_ref_t, a offset into 0172 * the page and the length of the area in that page. All scsiif_request_segment 0173 * areas concatenated form the resulting data buffer used by the operation. 0174 * If the number of scsiif_request_segment areas is not too large (less than 0175 * or equal VSCSIIF_SG_TABLESIZE) the areas can be specified directly in the 0176 * seg[] array and the number of valid scsiif_request_segment elements is to be 0177 * set in nr_segments. 0178 * 0179 * If "feature-sg-grant" in the Xenstore is set it is possible to specify more 0180 * than VSCSIIF_SG_TABLESIZE scsiif_request_segment elements via indirection. 0181 * The maximum number of allowed scsiif_request_segment elements is the value 0182 * of the "feature-sg-grant" entry from Xenstore. When using indirection the 0183 * seg[] array doesn't contain specifications of the data buffers, but 0184 * references to scsiif_request_segment arrays, which in turn reference the 0185 * data buffers. While nr_segments holds the number of populated seg[] entries 0186 * (plus the set VSCSIIF_SG_GRANT bit), the number of scsiif_request_segment 0187 * elements referencing the target data buffers is calculated from the lengths 0188 * of the seg[] elements (the sum of all valid seg[].length divided by the 0189 * size of one scsiif_request_segment structure). The frontend may use a mix of 0190 * direct and indirect requests. 0191 */ 0192 #define VSCSIIF_ACT_SCSI_CDB 1 0193 0194 /* 0195 * Request abort of a running operation for the specified target given by 0196 * channel, id, lun and the operation's rqid in ref_rqid. 0197 */ 0198 #define VSCSIIF_ACT_SCSI_ABORT 2 0199 0200 /* 0201 * Request a device reset of the specified target (channel and id). 0202 */ 0203 #define VSCSIIF_ACT_SCSI_RESET 3 0204 0205 /* 0206 * Preset scatter/gather elements for a following request. Deprecated. 0207 * Keeping the define only to avoid usage of the value "4" for other actions. 0208 */ 0209 #define VSCSIIF_ACT_SCSI_SG_PRESET 4 0210 0211 /* 0212 * Maximum scatter/gather segments per request. 0213 * 0214 * Considering balance between allocating at least 16 "vscsiif_request" 0215 * structures on one page (4096 bytes) and the number of scatter/gather 0216 * elements needed, we decided to use 26 as a magic number. 0217 * 0218 * If "feature-sg-grant" is set, more scatter/gather elements can be specified 0219 * by placing them in one or more (up to VSCSIIF_SG_TABLESIZE) granted pages. 0220 * In this case the vscsiif_request seg elements don't contain references to 0221 * the user data, but to the SG elements referencing the user data. 0222 */ 0223 #define VSCSIIF_SG_TABLESIZE 26 0224 0225 /* 0226 * based on Linux kernel 2.6.18, still valid 0227 * 0228 * Changing these values requires support of multiple protocols via the rings 0229 * as "old clients" will blindly use these values and the resulting structure 0230 * sizes. 0231 */ 0232 #define VSCSIIF_MAX_COMMAND_SIZE 16 0233 #define VSCSIIF_SENSE_BUFFERSIZE 96 0234 #define VSCSIIF_PAGE_SIZE 4096 0235 0236 struct scsiif_request_segment { 0237 grant_ref_t gref; 0238 uint16_t offset; 0239 uint16_t length; 0240 }; 0241 0242 #define VSCSIIF_SG_PER_PAGE (VSCSIIF_PAGE_SIZE / \ 0243 sizeof(struct scsiif_request_segment)) 0244 0245 /* Size of one request is 252 bytes */ 0246 struct vscsiif_request { 0247 uint16_t rqid; /* private guest value, echoed in resp */ 0248 uint8_t act; /* command between backend and frontend */ 0249 uint8_t cmd_len; /* valid CDB bytes */ 0250 0251 uint8_t cmnd[VSCSIIF_MAX_COMMAND_SIZE]; /* the CDB */ 0252 uint16_t timeout_per_command; /* deprecated */ 0253 uint16_t channel, id, lun; /* (virtual) device specification */ 0254 uint16_t ref_rqid; /* command abort reference */ 0255 uint8_t sc_data_direction; /* for DMA_TO_DEVICE(1) 0256 DMA_FROM_DEVICE(2) 0257 DMA_NONE(3) requests */ 0258 uint8_t nr_segments; /* Number of pieces of scatter-gather */ 0259 /* 0260 * flag in nr_segments: SG elements via grant page 0261 * 0262 * If VSCSIIF_SG_GRANT is set, the low 7 bits of nr_segments specify the number 0263 * of grant pages containing SG elements. Usable if "feature-sg-grant" set. 0264 */ 0265 #define VSCSIIF_SG_GRANT 0x80 0266 0267 struct scsiif_request_segment seg[VSCSIIF_SG_TABLESIZE]; 0268 uint32_t reserved[3]; 0269 }; 0270 0271 /* Size of one response is 252 bytes */ 0272 struct vscsiif_response { 0273 uint16_t rqid; /* identifies request */ 0274 uint8_t padding; 0275 uint8_t sense_len; 0276 uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE]; 0277 int32_t rslt; 0278 uint32_t residual_len; /* request bufflen - 0279 return the value from physical device */ 0280 uint32_t reserved[36]; 0281 }; 0282 0283 /* SCSI I/O status from vscsiif_response->rslt */ 0284 #define XEN_VSCSIIF_RSLT_STATUS(x) ((x) & 0x00ff) 0285 0286 /* Host I/O status from vscsiif_response->rslt */ 0287 #define XEN_VSCSIIF_RSLT_HOST(x) (((x) & 0x00ff0000) >> 16) 0288 #define XEN_VSCSIIF_RSLT_HOST_OK 0 0289 /* Couldn't connect before timeout */ 0290 #define XEN_VSCSIIF_RSLT_HOST_NO_CONNECT 1 0291 /* Bus busy through timeout */ 0292 #define XEN_VSCSIIF_RSLT_HOST_BUS_BUSY 2 0293 /* Timed out for other reason */ 0294 #define XEN_VSCSIIF_RSLT_HOST_TIME_OUT 3 0295 /* Bad target */ 0296 #define XEN_VSCSIIF_RSLT_HOST_BAD_TARGET 4 0297 /* Abort for some other reason */ 0298 #define XEN_VSCSIIF_RSLT_HOST_ABORT 5 0299 /* Parity error */ 0300 #define XEN_VSCSIIF_RSLT_HOST_PARITY 6 0301 /* Internal error */ 0302 #define XEN_VSCSIIF_RSLT_HOST_ERROR 7 0303 /* Reset by somebody */ 0304 #define XEN_VSCSIIF_RSLT_HOST_RESET 8 0305 /* Unexpected interrupt */ 0306 #define XEN_VSCSIIF_RSLT_HOST_BAD_INTR 9 0307 /* Force command past mid-layer */ 0308 #define XEN_VSCSIIF_RSLT_HOST_PASSTHROUGH 10 0309 /* Retry requested */ 0310 #define XEN_VSCSIIF_RSLT_HOST_SOFT_ERROR 11 0311 /* Hidden retry requested */ 0312 #define XEN_VSCSIIF_RSLT_HOST_IMM_RETRY 12 0313 /* Requeue command requested */ 0314 #define XEN_VSCSIIF_RSLT_HOST_REQUEUE 13 0315 /* Transport error disrupted I/O */ 0316 #define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_DISRUPTED 14 0317 /* Transport class fastfailed */ 0318 #define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_FAILFAST 15 0319 /* Permanent target failure */ 0320 #define XEN_VSCSIIF_RSLT_HOST_TARGET_FAILURE 16 0321 /* Permanent nexus failure on path */ 0322 #define XEN_VSCSIIF_RSLT_HOST_NEXUS_FAILURE 17 0323 /* Space allocation on device failed */ 0324 #define XEN_VSCSIIF_RSLT_HOST_ALLOC_FAILURE 18 0325 /* Medium error */ 0326 #define XEN_VSCSIIF_RSLT_HOST_MEDIUM_ERROR 19 0327 /* Transport marginal errors */ 0328 #define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_MARGINAL 20 0329 0330 /* Result values of reset operations */ 0331 #define XEN_VSCSIIF_RSLT_RESET_SUCCESS 0x2002 0332 #define XEN_VSCSIIF_RSLT_RESET_FAILED 0x2003 0333 0334 DEFINE_RING_TYPES(vscsiif, struct vscsiif_request, struct vscsiif_response); 0335 0336 0337 #endif /*__XEN__PUBLIC_IO_SCSI_H__*/
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |