diff options
Diffstat (limited to 'include/xen/interface/io')
| -rw-r--r-- | include/xen/interface/io/ring.h | 19 | ||||
| -rw-r--r-- | include/xen/interface/io/vscsiif.h | 133 | ||||
| -rw-r--r-- | include/xen/interface/io/xs_wire.h | 37 | 
3 files changed, 176 insertions, 13 deletions
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h index 2470ec45ebb2..ba4c4274b714 100644 --- a/include/xen/interface/io/ring.h +++ b/include/xen/interface/io/ring.h @@ -72,9 +72,8 @@ typedef unsigned int RING_IDX;   * of the shared memory area (PAGE_SIZE, for instance). To initialise   * the front half:   * - *     mytag_front_ring_t front_ring; - *     SHARED_RING_INIT((mytag_sring_t *)shared_page); - *     FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE); + *     mytag_front_ring_t ring; + *     XEN_FRONT_RING_INIT(&ring, (mytag_sring_t *)shared_page, PAGE_SIZE);   *   * Initializing the back follows similarly (note that only the front   * initializes the shared ring): @@ -146,6 +145,11 @@ struct __name##_back_ring {                                             \  #define FRONT_RING_INIT(_r, _s, __size) FRONT_RING_ATTACH(_r, _s, 0, __size) +#define XEN_FRONT_RING_INIT(r, s, size) do {                            \ +    SHARED_RING_INIT(s);                                                \ +    FRONT_RING_INIT(r, s, size);                                        \ +} while (0) +  #define BACK_RING_ATTACH(_r, _s, _i, __size) do {                       \      (_r)->rsp_prod_pvt = (_i);                                          \      (_r)->req_cons = (_i);                                              \ @@ -170,16 +174,21 @@ struct __name##_back_ring {                                             \      (RING_FREE_REQUESTS(_r) == 0)  /* Test if there are outstanding messages to be processed on a ring. */ -#define RING_HAS_UNCONSUMED_RESPONSES(_r)                               \ +#define XEN_RING_NR_UNCONSUMED_RESPONSES(_r)                            \      ((_r)->sring->rsp_prod - (_r)->rsp_cons) -#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({                             \ +#define XEN_RING_NR_UNCONSUMED_REQUESTS(_r) ({                          \      unsigned int req = (_r)->sring->req_prod - (_r)->req_cons;          \      unsigned int rsp = RING_SIZE(_r) -                                  \          ((_r)->req_cons - (_r)->rsp_prod_pvt);                          \      req < rsp ? req : rsp;                                              \  }) +#define RING_HAS_UNCONSUMED_RESPONSES(_r) \ +    (!!XEN_RING_NR_UNCONSUMED_RESPONSES(_r)) +#define RING_HAS_UNCONSUMED_REQUESTS(_r)  \ +    (!!XEN_RING_NR_UNCONSUMED_REQUESTS(_r)) +  /* Direct access to individual ring elements, by index. */  #define RING_GET_REQUEST(_r, _idx)                                      \      (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req)) diff --git a/include/xen/interface/io/vscsiif.h b/include/xen/interface/io/vscsiif.h index 1f6047d3de44..7ea4dc9611c4 100644 --- a/include/xen/interface/io/vscsiif.h +++ b/include/xen/interface/io/vscsiif.h @@ -43,7 +43,7 @@   *   *      A string specifying the backend device: either a 4-tuple "h:c:t:l"   *      (host, controller, target, lun, all integers), or a WWN (e.g. - *      "naa.60014054ac780582"). + *      "naa.60014054ac780582:0").   *   * v-dev   *      Values:         string @@ -87,6 +87,75 @@   *      response structures.   */ +/* + * Xenstore format in practice + * =========================== + * + * The backend driver uses a single_host:many_devices notation to manage domU + * devices. Everything is stored in /local/domain/<backend_domid>/backend/vscsi/. + * The xenstore layout looks like this (dom0 is assumed to be the backend_domid): + * + *     <domid>/<vhost>/feature-host = "0" + *     <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0" + *     <domid>/<vhost>/frontend-id = "<domid>" + *     <domid>/<vhost>/online = "1" + *     <domid>/<vhost>/state = "4" + *     <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1" or "naa.wwn:lun" + *     <domid>/<vhost>/vscsi-devs/dev-0/state = "4" + *     <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0" + *     <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2" + *     <domid>/<vhost>/vscsi-devs/dev-1/state = "4" + *     <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0" + * + * The frontend driver maintains its state in + * /local/domain/<domid>/device/vscsi/. + * + *     <vhost>/backend = "/local/domain/0/backend/vscsi/<domid>/<vhost>" + *     <vhost>/backend-id = "0" + *     <vhost>/event-channel = "20" + *     <vhost>/ring-ref = "43" + *     <vhost>/state = "4" + *     <vhost>/vscsi-devs/dev-0/state = "4" + *     <vhost>/vscsi-devs/dev-1/state = "4" + * + * In addition to the entries for backend and frontend these flags are stored + * for the toolstack: + * + *     <domid>/<vhost>/vscsi-devs/dev-1/p-devname = "/dev/$device" + *     <domid>/<vhost>/libxl_ctrl_index = "0" + * + * + * Backend/frontend protocol + * ========================= + * + * To create a vhost along with a device: + *     <domid>/<vhost>/feature-host = "0" + *     <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0" + *     <domid>/<vhost>/frontend-id = "<domid>" + *     <domid>/<vhost>/online = "1" + *     <domid>/<vhost>/state = "1" + *     <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1" + *     <domid>/<vhost>/vscsi-devs/dev-0/state = "1" + *     <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0" + * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-0/state become 4 + * + * To add another device to a vhost: + *     <domid>/<vhost>/state = "7" + *     <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2" + *     <domid>/<vhost>/vscsi-devs/dev-1/state = "1" + *     <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0" + * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-1/state become 4 + * + * To remove a device from a vhost: + *     <domid>/<vhost>/state = "7" + *     <domid>/<vhost>/vscsi-devs/dev-1/state = "5" + * Wait for <domid>/<vhost>/state to become 4 + * Wait for <domid>/<vhost>/vscsi-devs/dev-1/state become 6 + * Remove <domid>/<vhost>/vscsi-devs/dev-1/{state,p-dev,v-dev,p-devname} + * Remove <domid>/<vhost>/vscsi-devs/dev-1/ + * + */ +  /* Requests from the frontend to the backend */  /* @@ -117,7 +186,8 @@   * (plus the set VSCSIIF_SG_GRANT bit), the number of scsiif_request_segment   * elements referencing the target data buffers is calculated from the lengths   * of the seg[] elements (the sum of all valid seg[].length divided by the - * size of one scsiif_request_segment structure). + * size of one scsiif_request_segment structure). The frontend may use a mix of + * direct and indirect requests.   */  #define VSCSIIF_ACT_SCSI_CDB		1 @@ -154,12 +224,14 @@  /*   * based on Linux kernel 2.6.18, still valid + *   * Changing these values requires support of multiple protocols via the rings   * as "old clients" will blindly use these values and the resulting structure   * sizes.   */  #define VSCSIIF_MAX_COMMAND_SIZE	16  #define VSCSIIF_SENSE_BUFFERSIZE	96 +#define VSCSIIF_PAGE_SIZE		4096  struct scsiif_request_segment {  	grant_ref_t gref; @@ -167,7 +239,8 @@ struct scsiif_request_segment {  	uint16_t length;  }; -#define VSCSIIF_SG_PER_PAGE (PAGE_SIZE / sizeof(struct scsiif_request_segment)) +#define VSCSIIF_SG_PER_PAGE	(VSCSIIF_PAGE_SIZE / \ +				 sizeof(struct scsiif_request_segment))  /* Size of one request is 252 bytes */  struct vscsiif_request { @@ -207,6 +280,58 @@ struct vscsiif_response {  	uint32_t reserved[36];  }; +/* SCSI I/O status from vscsiif_response->rslt */ +#define XEN_VSCSIIF_RSLT_STATUS(x)  ((x) & 0x00ff) + +/* Host I/O status from vscsiif_response->rslt */ +#define XEN_VSCSIIF_RSLT_HOST(x)    (((x) & 0x00ff0000) >> 16) +#define XEN_VSCSIIF_RSLT_HOST_OK                   0 +/* Couldn't connect before timeout */ +#define XEN_VSCSIIF_RSLT_HOST_NO_CONNECT           1 +/* Bus busy through timeout */ +#define XEN_VSCSIIF_RSLT_HOST_BUS_BUSY             2 +/* Timed out for other reason */ +#define XEN_VSCSIIF_RSLT_HOST_TIME_OUT             3 +/* Bad target */ +#define XEN_VSCSIIF_RSLT_HOST_BAD_TARGET           4 +/* Abort for some other reason */ +#define XEN_VSCSIIF_RSLT_HOST_ABORT                5 +/* Parity error */ +#define XEN_VSCSIIF_RSLT_HOST_PARITY               6 +/* Internal error */ +#define XEN_VSCSIIF_RSLT_HOST_ERROR                7 +/* Reset by somebody */ +#define XEN_VSCSIIF_RSLT_HOST_RESET                8 +/* Unexpected interrupt */ +#define XEN_VSCSIIF_RSLT_HOST_BAD_INTR             9 +/* Force command past mid-layer */ +#define XEN_VSCSIIF_RSLT_HOST_PASSTHROUGH         10 +/* Retry requested */ +#define XEN_VSCSIIF_RSLT_HOST_SOFT_ERROR          11 +/* Hidden retry requested */ +#define XEN_VSCSIIF_RSLT_HOST_IMM_RETRY           12 +/* Requeue command requested */ +#define XEN_VSCSIIF_RSLT_HOST_REQUEUE             13 +/* Transport error disrupted I/O */ +#define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_DISRUPTED 14 +/* Transport class fastfailed */ +#define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_FAILFAST  15 +/* Permanent target failure */ +#define XEN_VSCSIIF_RSLT_HOST_TARGET_FAILURE      16 +/* Permanent nexus failure on path */ +#define XEN_VSCSIIF_RSLT_HOST_NEXUS_FAILURE       17 +/* Space allocation on device failed */ +#define XEN_VSCSIIF_RSLT_HOST_ALLOC_FAILURE       18 +/* Medium error */ +#define XEN_VSCSIIF_RSLT_HOST_MEDIUM_ERROR        19 +/* Transport marginal errors */ +#define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_MARGINAL  20 + +/* Result values of reset operations */ +#define XEN_VSCSIIF_RSLT_RESET_SUCCESS  0x2002 +#define XEN_VSCSIIF_RSLT_RESET_FAILED   0x2003 +  DEFINE_RING_TYPES(vscsiif, struct vscsiif_request, struct vscsiif_response); -#endif /*__XEN__PUBLIC_IO_SCSI_H__*/ + +#endif  /*__XEN__PUBLIC_IO_SCSI_H__*/ diff --git a/include/xen/interface/io/xs_wire.h b/include/xen/interface/io/xs_wire.h index d40a44f09b16..b62365478ac0 100644 --- a/include/xen/interface/io/xs_wire.h +++ b/include/xen/interface/io/xs_wire.h @@ -10,7 +10,8 @@  enum xsd_sockmsg_type  { -    XS_DEBUG, +    XS_CONTROL, +#define XS_DEBUG XS_CONTROL      XS_DIRECTORY,      XS_READ,      XS_GET_PERMS, @@ -30,8 +31,13 @@ enum xsd_sockmsg_type      XS_IS_DOMAIN_INTRODUCED,      XS_RESUME,      XS_SET_TARGET, -    XS_RESTRICT, -    XS_RESET_WATCHES, +    /* XS_RESTRICT has been removed */ +    XS_RESET_WATCHES = XS_SET_TARGET + 2, +    XS_DIRECTORY_PART, + +    XS_TYPE_COUNT,      /* Number of valid types. */ + +    XS_INVALID = 0xffff /* Guaranteed to remain an invalid type */  };  #define XS_WRITE_NONE "NONE" @@ -59,7 +65,8 @@ static struct xsd_errors xsd_errors[] __attribute__((unused)) = {      XSD_ERROR(EROFS),      XSD_ERROR(EBUSY),      XSD_ERROR(EAGAIN), -    XSD_ERROR(EISCONN) +    XSD_ERROR(EISCONN), +    XSD_ERROR(E2BIG)  };  struct xsd_sockmsg @@ -87,9 +94,31 @@ struct xenstore_domain_interface {      char rsp[XENSTORE_RING_SIZE]; /* Replies and async watch events. */      XENSTORE_RING_IDX req_cons, req_prod;      XENSTORE_RING_IDX rsp_cons, rsp_prod; +    uint32_t server_features; /* Bitmap of features supported by the server */ +    uint32_t connection; +    uint32_t error;  };  /* Violating this is very bad.  See docs/misc/xenstore.txt. */  #define XENSTORE_PAYLOAD_MAX 4096 +/* Violating these just gets you an error back */ +#define XENSTORE_ABS_PATH_MAX 3072 +#define XENSTORE_REL_PATH_MAX 2048 + +/* The ability to reconnect a ring */ +#define XENSTORE_SERVER_FEATURE_RECONNECTION 1 +/* The presence of the "error" field in the ring page */ +#define XENSTORE_SERVER_FEATURE_ERROR        2 + +/* Valid values for the connection field */ +#define XENSTORE_CONNECTED 0 /* the steady-state */ +#define XENSTORE_RECONNECT 1 /* guest has initiated a reconnect */ + +/* Valid values for the error field */ +#define XENSTORE_ERROR_NONE    0 /* No error */ +#define XENSTORE_ERROR_COMM    1 /* Communication problem */ +#define XENSTORE_ERROR_RINGIDX 2 /* Invalid ring index */ +#define XENSTORE_ERROR_PROTO   3 /* Protocol violation (payload too long) */ +  #endif /* _XS_WIRE_H */  | 
