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