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    bool seg_max_adjust;
  52    uint32_t max_sectors;
  53    uint32_t cmd_per_lun;
  54#ifdef CONFIG_VHOST_SCSI
  55    char *vhostfd;
  56    char *wwpn;
  57#endif
  58    CharBackend chardev;
  59    uint32_t boot_tpgt;
  60    IOThread *iothread;
  61};
  62
  63struct VirtIOSCSI;
  64
  65typedef struct VirtIOSCSICommon {
  66    VirtIODevice parent_obj;
  67    VirtIOSCSIConf conf;
  68
  69    uint32_t sense_size;
  70    uint32_t cdb_size;
  71    VirtQueue *ctrl_vq;
  72    VirtQueue *event_vq;
  73    VirtQueue **cmd_vqs;
  74} VirtIOSCSICommon;
  75
  76typedef struct VirtIOSCSI {
  77    VirtIOSCSICommon parent_obj;
  78
  79    SCSIBus bus;
  80    int resetting;
  81    bool events_dropped;
  82
  83    /* Fields for dataplane below */
  84    AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
  85
  86    bool dataplane_started;
  87    bool dataplane_starting;
  88    bool dataplane_stopping;
  89    bool dataplane_fenced;
  90    uint32_t host_features;
  91} VirtIOSCSI;
  92
  93typedef struct VirtIOSCSIReq {
  94    /* Note:
  95     * - fields up to resp_iov are initialized by virtio_scsi_init_req;
  96     * - fields starting at vring are zeroed by virtio_scsi_init_req.
  97     * */
  98    VirtQueueElement elem;
  99
 100    VirtIOSCSI *dev;
 101    VirtQueue *vq;
 102    QEMUSGList qsgl;
 103    QEMUIOVector resp_iov;
 104
 105    union {
 106        /* Used for two-stage request submission */
 107        QTAILQ_ENTRY(VirtIOSCSIReq) next;
 108
 109        /* Used for cancellation of request during TMFs */
 110        int remaining;
 111    };
 112
 113    SCSIRequest *sreq;
 114    size_t resp_size;
 115    enum SCSIXferMode mode;
 116    union {
 117        VirtIOSCSICmdResp     cmd;
 118        VirtIOSCSICtrlTMFResp tmf;
 119        VirtIOSCSICtrlANResp  an;
 120        VirtIOSCSIEvent       event;
 121    } resp;
 122    union {
 123        VirtIOSCSICmdReq      cmd;
 124        VirtIOSCSICtrlTMFReq  tmf;
 125        VirtIOSCSICtrlANReq   an;
 126    } req;
 127} VirtIOSCSIReq;
 128
 129static inline void virtio_scsi_acquire(VirtIOSCSI *s)
 130{
 131    if (s->ctx) {
 132        aio_context_acquire(s->ctx);
 133    }
 134}
 135
 136static inline void virtio_scsi_release(VirtIOSCSI *s)
 137{
 138    if (s->ctx) {
 139        aio_context_release(s->ctx);
 140    }
 141}
 142
 143void virtio_scsi_common_realize(DeviceState *dev,
 144                                VirtIOHandleOutput ctrl,
 145                                VirtIOHandleOutput evt,
 146                                VirtIOHandleOutput cmd,
 147                                Error **errp);
 148
 149void virtio_scsi_common_unrealize(DeviceState *dev);
 150bool virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq);
 151bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq);
 152bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq);
 153void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req);
 154void virtio_scsi_free_req(VirtIOSCSIReq *req);
 155void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
 156                            uint32_t event, uint32_t reason);
 157
 158void virtio_scsi_dataplane_setup(VirtIOSCSI *s, Error **errp);
 159int virtio_scsi_dataplane_start(VirtIODevice *s);
 160void virtio_scsi_dataplane_stop(VirtIODevice *s);
 161
 162#endif /* QEMU_VIRTIO_SCSI_H */
 163