qemu/include/hw/virtio/virtio-scsi.h
<<
>>
Prefs
   1/*
   2 * Virtio SCSI HBA
   3 *
   4 * Copyright IBM, Corp. 2010
   5 *
   6 * Authors:
   7 *  Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2.  See
  10 * the COPYING file in the top-level directory.
  11 *
  12 */
  13
  14#ifndef QEMU_VIRTIO_SCSI_H
  15#define QEMU_VIRTIO_SCSI_H
  16
  17/* Override CDB/sense data size: they are dynamic (guest controlled) in QEMU */
  18#define VIRTIO_SCSI_CDB_SIZE 0
  19#define VIRTIO_SCSI_SENSE_SIZE 0
  20#include "standard-headers/linux/virtio_scsi.h"
  21#include "hw/virtio/virtio.h"
  22#include "hw/pci/pci.h"
  23#include "hw/scsi/scsi.h"
  24#include "chardev/char-fe.h"
  25#include "sysemu/iothread.h"
  26
  27#define TYPE_VIRTIO_SCSI_COMMON "virtio-scsi-common"
  28#define VIRTIO_SCSI_COMMON(obj) \
  29        OBJECT_CHECK(VirtIOSCSICommon, (obj), TYPE_VIRTIO_SCSI_COMMON)
  30
  31#define TYPE_VIRTIO_SCSI "virtio-scsi-device"
  32#define VIRTIO_SCSI(obj) \
  33        OBJECT_CHECK(VirtIOSCSI, (obj), TYPE_VIRTIO_SCSI)
  34
  35#define VIRTIO_SCSI_MAX_CHANNEL 0
  36#define VIRTIO_SCSI_MAX_TARGET  255
  37#define VIRTIO_SCSI_MAX_LUN     16383
  38
  39typedef struct virtio_scsi_cmd_req VirtIOSCSICmdReq;
  40typedef struct virtio_scsi_cmd_resp VirtIOSCSICmdResp;
  41typedef struct virtio_scsi_ctrl_tmf_req VirtIOSCSICtrlTMFReq;
  42typedef struct virtio_scsi_ctrl_tmf_resp VirtIOSCSICtrlTMFResp;
  43typedef struct virtio_scsi_ctrl_an_req VirtIOSCSICtrlANReq;
  44typedef struct virtio_scsi_ctrl_an_resp VirtIOSCSICtrlANResp;
  45typedef struct virtio_scsi_event VirtIOSCSIEvent;
  46typedef struct virtio_scsi_config VirtIOSCSIConfig;
  47
  48struct VirtIOSCSIConf {
  49    uint32_t num_queues;
  50    uint32_t virtqueue_size;
  51    uint32_t max_sectors;
  52    uint32_t cmd_per_lun;
  53#ifdef CONFIG_VHOST_SCSI
  54    char *vhostfd;
  55    char *wwpn;
  56#endif
  57    CharBackend chardev;
  58    uint32_t boot_tpgt;
  59    IOThread *iothread;
  60};
  61
  62struct VirtIOSCSI;
  63
  64typedef struct VirtIOSCSICommon {
  65    VirtIODevice parent_obj;
  66    VirtIOSCSIConf conf;
  67
  68    uint32_t sense_size;
  69    uint32_t cdb_size;
  70    VirtQueue *ctrl_vq;
  71    VirtQueue *event_vq;
  72    VirtQueue **cmd_vqs;
  73} VirtIOSCSICommon;
  74
  75typedef struct VirtIOSCSI {
  76    VirtIOSCSICommon parent_obj;
  77
  78    SCSIBus bus;
  79    int resetting;
  80    bool events_dropped;
  81
  82    /* Fields for dataplane below */
  83    AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
  84
  85    bool dataplane_started;
  86    bool dataplane_starting;
  87    bool dataplane_stopping;
  88    bool dataplane_fenced;
  89    uint32_t host_features;
  90} VirtIOSCSI;
  91
  92typedef struct VirtIOSCSIReq {
  93    /* Note:
  94     * - fields up to resp_iov are initialized by virtio_scsi_init_req;
  95     * - fields starting at vring are zeroed by virtio_scsi_init_req.
  96     * */
  97    VirtQueueElement elem;
  98
  99    VirtIOSCSI *dev;
 100    VirtQueue *vq;
 101    QEMUSGList qsgl;
 102    QEMUIOVector resp_iov;
 103
 104    union {
 105        /* Used for two-stage request submission */
 106        QTAILQ_ENTRY(VirtIOSCSIReq) next;
 107
 108        /* Used for cancellation of request during TMFs */
 109        int remaining;
 110    };
 111
 112    SCSIRequest *sreq;
 113    size_t resp_size;
 114    enum SCSIXferMode mode;
 115    union {
 116        VirtIOSCSICmdResp     cmd;
 117        VirtIOSCSICtrlTMFResp tmf;
 118        VirtIOSCSICtrlANResp  an;
 119        VirtIOSCSIEvent       event;
 120    } resp;
 121    union {
 122        VirtIOSCSICmdReq      cmd;
 123        VirtIOSCSICtrlTMFReq  tmf;
 124        VirtIOSCSICtrlANReq   an;
 125    } req;
 126} VirtIOSCSIReq;
 127
 128static inline void virtio_scsi_acquire(VirtIOSCSI *s)
 129{
 130    if (s->ctx) {
 131        aio_context_acquire(s->ctx);
 132    }
 133}
 134
 135static inline void virtio_scsi_release(VirtIOSCSI *s)
 136{
 137    if (s->ctx) {
 138        aio_context_release(s->ctx);
 139    }
 140}
 141
 142void virtio_scsi_common_realize(DeviceState *dev,
 143                                VirtIOHandleOutput ctrl,
 144                                VirtIOHandleOutput evt,
 145                                VirtIOHandleOutput cmd,
 146                                Error **errp);
 147
 148void virtio_scsi_common_unrealize(DeviceState *dev);
 149bool virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq);
 150bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq);
 151bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq);
 152void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req);
 153void virtio_scsi_free_req(VirtIOSCSIReq *req);
 154void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
 155                            uint32_t event, uint32_t reason);
 156
 157void virtio_scsi_dataplane_setup(VirtIOSCSI *s, Error **errp);
 158int virtio_scsi_dataplane_start(VirtIODevice *s);
 159void virtio_scsi_dataplane_stop(VirtIODevice *s);
 160
 161#endif /* QEMU_VIRTIO_SCSI_H */
 162