Commit 6165daa4 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'bonzini/scsi-next' into staging



# By Paolo Bonzini (5) and others
# Via Paolo Bonzini
* bonzini/scsi-next:
  vhost-scsi-s390: new device supporting the tcm_vhost Linux kernel module
  vhost-scsi-ccw: new device supporting the tcm_vhost Linux kernel module
  vhost-scsi-pci: new device supporting the tcm_vhost Linux kernel module
  vhost-scsi: new device supporting the tcm_vhost Linux kernel module
  virtio: simplify Makefile conditionals
  virtio-scsi: create VirtIOSCSICommon
  vhost: Add vhost_commit callback for SeaBIOS ROM region re-mapping
  scsi: VMWare PVSCSI paravirtual device implementation
  scsi: avoid assertion failure on VERIFY command

Message-id: 1366381460-6041-1-git-send-email-pbonzini@redhat.com
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parents d6394988 d6e51919
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@ libattr=""
xfs=""

vhost_net="no"
vhost_scsi="no"
kvm="no"
gprof="no"
debug_tcg="no"
@@ -543,6 +544,7 @@ Haiku)
  usb="linux"
  kvm="yes"
  vhost_net="yes"
  vhost_scsi="yes"
  if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
    audio_possible_drivers="$audio_possible_drivers fmod"
  fi
@@ -870,6 +872,10 @@ for opt do
  ;;
  --enable-vhost-net) vhost_net="yes"
  ;;
  --disable-vhost-scsi) vhost_scsi="no"
  ;;
  --enable-vhost-scsi) vhost_scsi="yes"
  ;;
  --disable-glx) glx="no"
  ;;
  --enable-glx) glx="yes"
@@ -3553,6 +3559,7 @@ echo "sigev_thread_id $sigev_thread_id"
echo "uuid support      $uuid"
echo "libcap-ng support $cap_ng"
echo "vhost-net support $vhost_net"
echo "vhost-scsi support $vhost_scsi"
echo "Trace backend     $trace_backend"
echo "Trace output file $trace_file-<pid>"
echo "spice support     $spice ($spice_protocol_version/$spice_server_version)"
@@ -3836,6 +3843,9 @@ fi
if test "$virtfs" = "yes" ; then
  echo "CONFIG_VIRTFS=y" >> $config_host_mak
fi
if test "$vhost_scsi" = "yes" ; then
  echo "CONFIG_VHOST_SCSI=y" >> $config_host_mak
fi
if test "$blobs" = "yes" ; then
  echo "INSTALL_BLOBS=yes" >> $config_host_mak
fi
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ CONFIG_EEPRO100_PCI=y
CONFIG_PCNET_PCI=y
CONFIG_PCNET_COMMON=y
CONFIG_LSI_SCSI_PCI=y
CONFIG_VMW_PVSCSI_SCSI_PCI=y
CONFIG_MEGASAS_SCSI_PCI=y
CONFIG_RTL8139_PCI=y
CONFIG_E1000_PCI=y
+92 −0
Original line number Diff line number Diff line
General Description
===================

This document describes VMWare PVSCSI device interface specification.
Created by Dmitry Fleytman (dmitry@daynix.com), Daynix Computing LTD.
Based on source code of PVSCSI Linux driver from kernel 3.0.4

PVSCSI Device Interface Overview
================================

The interface is based on memory area shared between hypervisor and VM.
Memory area is obtained by driver as device IO memory resource of
PVSCSI_MEM_SPACE_SIZE length.
The shared memory consists of registers area and rings area.
The registers area is used to raise hypervisor interrupts and issue device
commands. The rings area is used to transfer data descriptors and SCSI
commands from VM to hypervisor and to transfer messages produced by
hypervisor to VM. Data itself is transferred via virtual scatter-gather DMA.

PVSCSI Device Registers
=======================

The length of the registers area is 1 page (PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES).
The structure of the registers area is described by the PVSCSIRegOffset enum.
There are registers to issue device command (with optional short data),
issue device interrupt, control interrupts masking.

PVSCSI Device Rings
===================

There are three rings in shared memory:

    1. Request ring (struct PVSCSIRingReqDesc *req_ring)
        - ring for OS to device requests
    2. Completion ring (struct PVSCSIRingCmpDesc *cmp_ring)
        - ring for device request completions
    3. Message ring (struct PVSCSIRingMsgDesc *msg_ring)
        - ring for messages from device.
       This ring is optional and the guest might not configure it.
There is a control area (struct PVSCSIRingsState *rings_state) used to control
rings operation.

PVSCSI Device to Host Interrupts
================================
There are following interrupt types supported by PVSCSI device:
    1. Completion interrupts (completion ring notifications):
        PVSCSI_INTR_CMPL_0
        PVSCSI_INTR_CMPL_1
    2. Message interrupts (message ring notifications):
        PVSCSI_INTR_MSG_0
        PVSCSI_INTR_MSG_1

Interrupts are controlled via PVSCSI_REG_OFFSET_INTR_MASK register
Bit set means interrupt enabled, bit cleared - disabled

Interrupt modes supported are legacy, MSI and MSI-X
In case of legacy interrupts, register PVSCSI_REG_OFFSET_INTR_STATUS
is used to check which interrupt has arrived.  Interrupts are
acknowledged when the corresponding bit is written to the interrupt
status register.

PVSCSI Device Operation Sequences
=================================

1. Startup sequence:
    a. Issue PVSCSI_CMD_ADAPTER_RESET command;
    aa. Windows driver reads interrupt status register here;
    b. Issue PVSCSI_CMD_SETUP_MSG_RING command with no additional data,
       check status and disable device messages if error returned;
       (Omitted if device messages disabled by driver configuration)
    c. Issue PVSCSI_CMD_SETUP_RINGS command, provide rings configuration
       as struct PVSCSICmdDescSetupRings;
    d. Issue PVSCSI_CMD_SETUP_MSG_RING command again, provide
       rings configuration as struct PVSCSICmdDescSetupMsgRing;
    e. Unmask completion and message (if device messages enabled) interrupts.

2. Shutdown sequences
    a. Mask interrupts;
    b. Flush request ring using PVSCSI_REG_OFFSET_KICK_NON_RW_IO;
    c. Issue PVSCSI_CMD_ADAPTER_RESET command.

3. Send request
    a. Fill next free request ring descriptor;
    b. Issue PVSCSI_REG_OFFSET_KICK_RW_IO for R/W operations;
       or PVSCSI_REG_OFFSET_KICK_NON_RW_IO for other operations.

4. Abort command
    a. Issue PVSCSI_CMD_ABORT_CMD command;

5. Request completion processing
    a. Upon completion interrupt arrival process completion
       and message (if enabled) rings.
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += ssi/
devices-dirs-$(CONFIG_SOFTMMU) += timer/
devices-dirs-$(CONFIG_TPM) += tpm/
devices-dirs-$(CONFIG_SOFTMMU) += usb/
devices-dirs-$(CONFIG_SOFTMMU) += virtio/
devices-dirs-$(CONFIG_VIRTIO) += virtio/
devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
devices-dirs-$(CONFIG_SOFTMMU) += xen/
devices-dirs-y += core/
+50 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include "hw/virtio/virtio-rng.h"
#include "hw/virtio/virtio-serial.h"
#include "hw/virtio/virtio-net.h"
#include "hw/virtio/vhost-scsi.h"
#include "hw/sysbus.h"
#include "sysemu/kvm.h"

@@ -239,6 +240,28 @@ static void s390_virtio_scsi_instance_init(Object *obj)
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}

#ifdef CONFIG_VHOST_SCSI
static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev)
{
    VHostSCSIS390 *dev = VHOST_SCSI_S390(s390_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);

    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
    if (qdev_init(vdev) < 0) {
        return -1;
    }

    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
}

static void s390_vhost_scsi_instance_init(Object *obj)
{
    VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);
    object_initialize(OBJECT(&dev->vdev), TYPE_VHOST_SCSI);
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
#endif

static int s390_virtio_rng_init(VirtIOS390Device *dev)
{
    VirtIODevice *vdev;
@@ -560,7 +583,7 @@ static const TypeInfo virtio_s390_device_info = {
};

static Property s390_virtio_scsi_properties[] = {
    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIS390, vdev.conf),
    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIS390, vdev.parent_obj.conf),
    DEFINE_VIRTIO_SCSI_FEATURES(VirtIOS390Device, host_features),
    DEFINE_PROP_END_OF_LIST(),
};
@@ -582,6 +605,31 @@ static const TypeInfo s390_virtio_scsi = {
    .class_init    = s390_virtio_scsi_class_init,
};

#ifdef CONFIG_VHOST_SCSI
static Property s390_vhost_scsi_properties[] = {
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
    DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIS390, vdev.parent_obj.conf),
    DEFINE_PROP_END_OF_LIST(),
};

static void s390_vhost_scsi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);

    k->init = s390_vhost_scsi_init;
    dc->props = s390_vhost_scsi_properties;
}

static const TypeInfo s390_vhost_scsi = {
    .name          = TYPE_VHOST_SCSI_S390,
    .parent        = TYPE_VIRTIO_S390_DEVICE,
    .instance_size = sizeof(VHostSCSIS390),
    .instance_init = s390_vhost_scsi_instance_init,
    .class_init    = s390_vhost_scsi_class_init,
};
#endif

/***************** S390 Virtio Bus Bridge Device *******************/
/* Only required to have the virtio bus as child in the system bus */

@@ -643,6 +691,7 @@ static void s390_virtio_register_types(void)
    type_register_static(&s390_virtio_blk);
    type_register_static(&s390_virtio_net);
    type_register_static(&s390_virtio_scsi);
    type_register_static(&s390_vhost_scsi);
    type_register_static(&s390_virtio_rng);
    type_register_static(&s390_virtio_bridge_info);
}
Loading