qemu/include/hw/virtio/virtio-scsi.h
Shannon Zhao da2f84d127 virtio-scsi: Move DEFINE_VIRTIO_SCSI_FEATURES to virtio-scsi
So far virtio-scsi-device can't expose host features to guest while
using virtio-mmio because it doesn't set DEFINE_VIRTIO_SCSI_FEATURES on
backend or transport.

The host features belong to the backends while virtio-scsi-pci,
virtio-scsi-s390 and virtio-scsi-ccw set the DEFINE_VIRTIO_SCSI_FEATURES
on transports. But they already have the ability to forward property
accesses to the backend child. So if we move the host features to
backends, it doesn't break the backwards compatibility for them and
make host features work while using virtio-mmio.

Move DEFINE_VIRTIO_SCSI_FEATURES to the backend virtio-scsi. The
transports just sync the host features from backends.

Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-28 17:44:40 +02:00

180 lines
5.7 KiB
C

/*
* Virtio SCSI HBA
*
* Copyright IBM, Corp. 2010
*
* Authors:
* Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
*/
#ifndef _QEMU_VIRTIO_SCSI_H
#define _QEMU_VIRTIO_SCSI_H
/* Override CDB/sense data size: they are dynamic (guest controlled) in QEMU */
#define VIRTIO_SCSI_CDB_SIZE 0
#define VIRTIO_SCSI_SENSE_SIZE 0
#include "standard-headers/linux/virtio_scsi.h"
#include "hw/virtio/virtio.h"
#include "hw/pci/pci.h"
#include "hw/scsi/scsi.h"
#include "sysemu/iothread.h"
#include "hw/virtio/dataplane/vring.h"
#define TYPE_VIRTIO_SCSI_COMMON "virtio-scsi-common"
#define VIRTIO_SCSI_COMMON(obj) \
OBJECT_CHECK(VirtIOSCSICommon, (obj), TYPE_VIRTIO_SCSI_COMMON)
#define TYPE_VIRTIO_SCSI "virtio-scsi-device"
#define VIRTIO_SCSI(obj) \
OBJECT_CHECK(VirtIOSCSI, (obj), TYPE_VIRTIO_SCSI)
#define VIRTIO_SCSI_VQ_SIZE 128
#define VIRTIO_SCSI_MAX_CHANNEL 0
#define VIRTIO_SCSI_MAX_TARGET 255
#define VIRTIO_SCSI_MAX_LUN 16383
typedef struct virtio_scsi_cmd_req VirtIOSCSICmdReq;
typedef struct virtio_scsi_cmd_resp VirtIOSCSICmdResp;
typedef struct virtio_scsi_ctrl_tmf_req VirtIOSCSICtrlTMFReq;
typedef struct virtio_scsi_ctrl_tmf_resp VirtIOSCSICtrlTMFResp;
typedef struct virtio_scsi_ctrl_an_req VirtIOSCSICtrlANReq;
typedef struct virtio_scsi_ctrl_an_resp VirtIOSCSICtrlANResp;
typedef struct virtio_scsi_event VirtIOSCSIEvent;
typedef struct virtio_scsi_config VirtIOSCSIConfig;
struct VirtIOSCSIConf {
uint32_t num_queues;
uint32_t max_sectors;
uint32_t cmd_per_lun;
char *vhostfd;
char *wwpn;
uint32_t boot_tpgt;
IOThread *iothread;
};
struct VirtIOSCSI;
typedef struct {
struct VirtIOSCSI *parent;
Vring vring;
EventNotifier host_notifier;
EventNotifier guest_notifier;
} VirtIOSCSIVring;
typedef struct VirtIOSCSICommon {
VirtIODevice parent_obj;
VirtIOSCSIConf conf;
uint32_t sense_size;
uint32_t cdb_size;
VirtQueue *ctrl_vq;
VirtQueue *event_vq;
VirtQueue **cmd_vqs;
} VirtIOSCSICommon;
typedef struct VirtIOSCSI {
VirtIOSCSICommon parent_obj;
SCSIBus bus;
int resetting;
bool events_dropped;
/* Fields for dataplane below */
AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
/* Vring is used instead of vq in dataplane code, because of the underlying
* memory layer thread safety */
VirtIOSCSIVring *ctrl_vring;
VirtIOSCSIVring *event_vring;
VirtIOSCSIVring **cmd_vrings;
bool dataplane_started;
bool dataplane_starting;
bool dataplane_stopping;
bool dataplane_disabled;
bool dataplane_fenced;
Error *blocker;
Notifier migration_state_notifier;
uint32_t host_features;
} VirtIOSCSI;
typedef struct VirtIOSCSIReq {
VirtIOSCSI *dev;
VirtQueue *vq;
QEMUSGList qsgl;
QEMUIOVector resp_iov;
/* Note:
* - fields before elem are initialized by virtio_scsi_init_req;
* - elem is uninitialized at the time of allocation.
* - fields after elem are zeroed by virtio_scsi_init_req.
* */
VirtQueueElement elem;
/* Set by dataplane code. */
VirtIOSCSIVring *vring;
union {
/* Used for two-stage request submission */
QTAILQ_ENTRY(VirtIOSCSIReq) next;
/* Used for cancellation of request during TMFs */
int remaining;
};
SCSIRequest *sreq;
size_t resp_size;
enum SCSIXferMode mode;
union {
VirtIOSCSICmdResp cmd;
VirtIOSCSICtrlTMFResp tmf;
VirtIOSCSICtrlANResp an;
VirtIOSCSIEvent event;
} resp;
union {
VirtIOSCSICmdReq cmd;
VirtIOSCSICtrlTMFReq tmf;
VirtIOSCSICtrlANReq an;
} req;
} VirtIOSCSIReq;
#define DEFINE_VIRTIO_SCSI_PROPERTIES(_state, _conf_field) \
DEFINE_PROP_UINT32("num_queues", _state, _conf_field.num_queues, 1), \
DEFINE_PROP_UINT32("max_sectors", _state, _conf_field.max_sectors, 0xFFFF),\
DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128)
#define DEFINE_VIRTIO_SCSI_FEATURES(_state, _feature_field) \
DEFINE_PROP_BIT("any_layout", _state, _feature_field, \
VIRTIO_F_ANY_LAYOUT, true), \
DEFINE_PROP_BIT("hotplug", _state, _feature_field, VIRTIO_SCSI_F_HOTPLUG, \
true), \
DEFINE_PROP_BIT("param_change", _state, _feature_field, \
VIRTIO_SCSI_F_CHANGE, true)
typedef void (*HandleOutput)(VirtIODevice *, VirtQueue *);
void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
HandleOutput ctrl, HandleOutput evt,
HandleOutput cmd);
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp);
void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req);
bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req);
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req);
VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq);
void virtio_scsi_free_req(VirtIOSCSIReq *req);
void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
uint32_t event, uint32_t reason);
void virtio_scsi_set_iothread(VirtIOSCSI *s, IOThread *iothread);
void virtio_scsi_dataplane_start(VirtIOSCSI *s);
void virtio_scsi_dataplane_stop(VirtIOSCSI *s);
void virtio_scsi_vring_push_notify(VirtIOSCSIReq *req);
VirtIOSCSIReq *virtio_scsi_pop_req_vring(VirtIOSCSI *s,
VirtIOSCSIVring *vring);
#endif /* _QEMU_VIRTIO_SCSI_H */