Home | History | Annotate | Line # | Download | only in io
      1 /******************************************************************************
      2  * vscsiif.h
      3  *
      4  * Based on the blkif.h code.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to
      8  * deal in the Software without restriction, including without limitation the
      9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     10  * sell copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  *
     24  * Copyright(c) FUJITSU Limited 2008.
     25  */
     26 
     27 #ifndef __XEN__PUBLIC_IO_SCSI_H__
     28 #define __XEN__PUBLIC_IO_SCSI_H__
     29 
     30 #include "ring.h"
     31 #include "../grant_table.h"
     32 
     33 /*
     34  * Feature and Parameter Negotiation
     35  * =================================
     36  * The two halves of a Xen pvSCSI driver utilize nodes within the XenStore to
     37  * communicate capabilities and to negotiate operating parameters.  This
     38  * section enumerates these nodes which reside in the respective front and
     39  * backend portions of the XenStore, following the XenBus convention.
     40  *
     41  * Any specified default value is in effect if the corresponding XenBus node
     42  * is not present in the XenStore.
     43  *
     44  * XenStore nodes in sections marked "PRIVATE" are solely for use by the
     45  * driver side whose XenBus tree contains them.
     46  *
     47  *****************************************************************************
     48  *                            Backend XenBus Nodes
     49  *****************************************************************************
     50  *
     51  *------------------ Backend Device Identification (PRIVATE) ------------------
     52  *
     53  * p-devname
     54  *      Values:         string
     55  *
     56  *      A free string used to identify the physical device (e.g. a disk name).
     57  *
     58  * p-dev
     59  *      Values:         string
     60  *
     61  *      A string specifying the backend device: either a 4-tuple "h:c:t:l"
     62  *      (host, controller, target, lun, all integers), or a WWN (e.g.
     63  *      "naa.60014054ac780582:0").
     64  *
     65  * v-dev
     66  *      Values:         string
     67  *
     68  *      A string specifying the frontend device in form of a 4-tuple "h:c:t:l"
     69  *      (host, controller, target, lun, all integers).
     70  *
     71  *--------------------------------- Features ---------------------------------
     72  *
     73  * feature-sg-grant
     74  *      Values:         unsigned [VSCSIIF_SG_TABLESIZE...65535]
     75  *      Default Value:  0
     76  *
     77  *      Specifies the maximum number of scatter/gather elements in grant pages
     78  *      supported. If not set, the backend supports up to VSCSIIF_SG_TABLESIZE
     79  *      SG elements specified directly in the request.
     80  *
     81  *****************************************************************************
     82  *                            Frontend XenBus Nodes
     83  *****************************************************************************
     84  *
     85  *----------------------- Request Transport Parameters -----------------------
     86  *
     87  * event-channel
     88  *      Values:         unsigned
     89  *
     90  *      The identifier of the Xen event channel used to signal activity
     91  *      in the ring buffer.
     92  *
     93  * ring-ref
     94  *      Values:         unsigned
     95  *
     96  *      The Xen grant reference granting permission for the backend to map
     97  *      the sole page in a single page sized ring buffer.
     98  *
     99  * protocol
    100  *      Values:         string (XEN_IO_PROTO_ABI_*)
    101  *      Default Value:  XEN_IO_PROTO_ABI_NATIVE
    102  *
    103  *      The machine ABI rules governing the format of all ring request and
    104  *      response structures.
    105  */
    106 
    107 /*
    108  * Xenstore format in practice
    109  * ===========================
    110  *
    111  * The backend driver uses a single_host:many_devices notation to manage domU
    112  * devices. Everything is stored in /local/domain/<backend_domid>/backend/vscsi/.
    113  * The xenstore layout looks like this (dom0 is assumed to be the backend_domid):
    114  *
    115  *     <domid>/<vhost>/feature-host = "0"
    116  *     <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0"
    117  *     <domid>/<vhost>/frontend-id = "<domid>"
    118  *     <domid>/<vhost>/online = "1"
    119  *     <domid>/<vhost>/state = "4"
    120  *     <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1" or "naa.wwn:lun"
    121  *     <domid>/<vhost>/vscsi-devs/dev-0/state = "4"
    122  *     <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0"
    123  *     <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2"
    124  *     <domid>/<vhost>/vscsi-devs/dev-1/state = "4"
    125  *     <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0"
    126  *
    127  * The frontend driver maintains its state in
    128  * /local/domain/<domid>/device/vscsi/.
    129  *
    130  *     <vhost>/backend = "/local/domain/0/backend/vscsi/<domid>/<vhost>"
    131  *     <vhost>/backend-id = "0"
    132  *     <vhost>/event-channel = "20"
    133  *     <vhost>/ring-ref = "43"
    134  *     <vhost>/state = "4"
    135  *     <vhost>/vscsi-devs/dev-0/state = "4"
    136  *     <vhost>/vscsi-devs/dev-1/state = "4"
    137  *
    138  * In addition to the entries for backend and frontend these flags are stored
    139  * for the toolstack:
    140  *
    141  *     <domid>/<vhost>/vscsi-devs/dev-1/p-devname = "/dev/$device"
    142  *     <domid>/<vhost>/libxl_ctrl_index = "0"
    143  *
    144  *
    145  * Backend/frontend protocol
    146  * =========================
    147  *
    148  * To create a vhost along with a device:
    149  *     <domid>/<vhost>/feature-host = "0"
    150  *     <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0"
    151  *     <domid>/<vhost>/frontend-id = "<domid>"
    152  *     <domid>/<vhost>/online = "1"
    153  *     <domid>/<vhost>/state = "1"
    154  *     <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1"
    155  *     <domid>/<vhost>/vscsi-devs/dev-0/state = "1"
    156  *     <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0"
    157  * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-0/state become 4
    158  *
    159  * To add another device to a vhost:
    160  *     <domid>/<vhost>/state = "7"
    161  *     <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2"
    162  *     <domid>/<vhost>/vscsi-devs/dev-1/state = "1"
    163  *     <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0"
    164  * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-1/state become 4
    165  *
    166  * To remove a device from a vhost:
    167  *     <domid>/<vhost>/state = "7"
    168  *     <domid>/<vhost>/vscsi-devs/dev-1/state = "5"
    169  * Wait for <domid>/<vhost>/state to become 4
    170  * Wait for <domid>/<vhost>/vscsi-devs/dev-1/state become 6
    171  * Remove <domid>/<vhost>/vscsi-devs/dev-1/{state,p-dev,v-dev,p-devname}
    172  * Remove <domid>/<vhost>/vscsi-devs/dev-1/
    173  *
    174  */
    175 
    176 /* Requests from the frontend to the backend */
    177 
    178 /*
    179  * Request a SCSI operation specified via a CDB in vscsiif_request.cmnd.
    180  * The target is specified via channel, id and lun.
    181  *
    182  * The operation to be performed is specified via a CDB in cmnd[], the length
    183  * of the CDB is in cmd_len. sc_data_direction specifies the direction of data
    184  * (to the device, from the device, or none at all).
    185  *
    186  * If data is to be transferred to or from the device the buffer(s) in the
    187  * guest memory is/are specified via one or multiple scsiif_request_segment
    188  * descriptors each specifying a memory page via a grant_ref_t, a offset into
    189  * the page and the length of the area in that page. All scsiif_request_segment
    190  * areas concatenated form the resulting data buffer used by the operation.
    191  * If the number of scsiif_request_segment areas is not too large (less than
    192  * or equal VSCSIIF_SG_TABLESIZE) the areas can be specified directly in the
    193  * seg[] array and the number of valid scsiif_request_segment elements is to be
    194  * set in nr_segments.
    195  *
    196  * If "feature-sg-grant" in the Xenstore is set it is possible to specify more
    197  * than VSCSIIF_SG_TABLESIZE scsiif_request_segment elements via indirection.
    198  * The maximum number of allowed scsiif_request_segment elements is the value
    199  * of the "feature-sg-grant" entry from Xenstore. When using indirection the
    200  * seg[] array doesn't contain specifications of the data buffers, but
    201  * references to scsiif_request_segment arrays, which in turn reference the
    202  * data buffers. While nr_segments holds the number of populated seg[] entries
    203  * (plus the set VSCSIIF_SG_GRANT bit), the number of scsiif_request_segment
    204  * elements referencing the target data buffers is calculated from the lengths
    205  * of the seg[] elements (the sum of all valid seg[].length divided by the
    206  * size of one scsiif_request_segment structure). The frontend may use a mix of
    207  * direct and indirect requests.
    208  */
    209 #define VSCSIIF_ACT_SCSI_CDB         1
    210 
    211 /*
    212  * Request abort of a running operation for the specified target given by
    213  * channel, id, lun and the operation's rqid in ref_rqid.
    214  */
    215 #define VSCSIIF_ACT_SCSI_ABORT       2
    216 
    217 /*
    218  * Request a device reset of the specified target (channel and id).
    219  */
    220 #define VSCSIIF_ACT_SCSI_RESET       3
    221 
    222 /*
    223  * Preset scatter/gather elements for a following request. Deprecated.
    224  * Keeping the define only to avoid usage of the value "4" for other actions.
    225  */
    226 #define VSCSIIF_ACT_SCSI_SG_PRESET   4
    227 
    228 /*
    229  * Maximum scatter/gather segments per request.
    230  *
    231  * Considering balance between allocating at least 16 "vscsiif_request"
    232  * structures on one page (4096 bytes) and the number of scatter/gather
    233  * elements needed, we decided to use 26 as a magic number.
    234  *
    235  * If "feature-sg-grant" is set, more scatter/gather elements can be specified
    236  * by placing them in one or more (up to VSCSIIF_SG_TABLESIZE) granted pages.
    237  * In this case the vscsiif_request seg elements don't contain references to
    238  * the user data, but to the SG elements referencing the user data.
    239  */
    240 #define VSCSIIF_SG_TABLESIZE             26
    241 
    242 /*
    243  * based on Linux kernel 2.6.18, still valid
    244  *
    245  * Changing these values requires support of multiple protocols via the rings
    246  * as "old clients" will blindly use these values and the resulting structure
    247  * sizes.
    248  */
    249 #define VSCSIIF_MAX_COMMAND_SIZE         16
    250 #define VSCSIIF_SENSE_BUFFERSIZE         96
    251 #define VSCSIIF_PAGE_SIZE              4096
    252 
    253 struct scsiif_request_segment {
    254     grant_ref_t gref;
    255     uint16_t offset;
    256     uint16_t length;
    257 };
    258 typedef struct scsiif_request_segment vscsiif_segment_t;
    259 
    260 #define VSCSIIF_SG_PER_PAGE (VSCSIIF_PAGE_SIZE / sizeof(struct scsiif_request_segment))
    261 
    262 /* Size of one request is 252 bytes */
    263 struct vscsiif_request {
    264     uint16_t rqid;          /* private guest value, echoed in resp  */
    265     uint8_t act;            /* command between backend and frontend */
    266     uint8_t cmd_len;        /* valid CDB bytes */
    267 
    268     uint8_t cmnd[VSCSIIF_MAX_COMMAND_SIZE]; /* the CDB */
    269     uint16_t timeout_per_command;   /* deprecated: timeout in secs, 0=default */
    270     uint16_t channel, id, lun;      /* (virtual) device specification */
    271     uint16_t ref_rqid;              /* command abort reference */
    272     uint8_t sc_data_direction;      /* for DMA_TO_DEVICE(1)
    273                                        DMA_FROM_DEVICE(2)
    274                                        DMA_NONE(3) requests  */
    275     uint8_t nr_segments;            /* Number of pieces of scatter-gather */
    276 /*
    277  * flag in nr_segments: SG elements via grant page
    278  *
    279  * If VSCSIIF_SG_GRANT is set, the low 7 bits of nr_segments specify the number
    280  * of grant pages containing SG elements. Usable if "feature-sg-grant" set.
    281  */
    282 #define VSCSIIF_SG_GRANT    0x80
    283 
    284     vscsiif_segment_t seg[VSCSIIF_SG_TABLESIZE];
    285     uint32_t reserved[3];
    286 };
    287 typedef struct vscsiif_request vscsiif_request_t;
    288 
    289 /*
    290  * The following interface is deprecated!
    291  */
    292 #define VSCSIIF_SG_LIST_SIZE ((sizeof(vscsiif_request_t) - 4) \
    293                               / sizeof(vscsiif_segment_t))
    294 
    295 struct vscsiif_sg_list {
    296     /* First two fields must match struct vscsiif_request! */
    297     uint16_t rqid;          /* private guest value, must match main req */
    298     uint8_t act;            /* VSCSIIF_ACT_SCSI_SG_PRESET */
    299     uint8_t nr_segments;    /* Number of pieces of scatter-gather */
    300     vscsiif_segment_t seg[VSCSIIF_SG_LIST_SIZE];
    301 };
    302 typedef struct vscsiif_sg_list vscsiif_sg_list_t;
    303 /* End of deprecated interface */
    304 
    305 /* Size of one response is 252 bytes */
    306 struct vscsiif_response {
    307     uint16_t rqid;          /* identifies request */
    308     uint8_t act;            /* deprecated: valid only if SG_PRESET supported */
    309     uint8_t sense_len;
    310     uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE];
    311     int32_t rslt;
    312     uint32_t residual_len;     /* request bufflen -
    313                                   return the value from physical device */
    314     uint32_t reserved[36];
    315 };
    316 typedef struct vscsiif_response vscsiif_response_t;
    317 
    318 DEFINE_RING_TYPES(vscsiif, struct vscsiif_request, struct vscsiif_response);
    319 
    320 
    321 #endif  /*__XEN__PUBLIC_IO_SCSI_H__*/
    322 /*
    323  * Local variables:
    324  * mode: C
    325  * c-file-style: "BSD"
    326  * c-basic-offset: 4
    327  * tab-width: 4
    328  * indent-tabs-mode: nil
    329  * End:
    330  */
    331