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