Back to home page

OSCL-LXR

 
 

    


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__*/