mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 17:23:56 -06:00
Merge remote-tracking branch 'remotes/bonzini/scsi-next' into staging
* remotes/bonzini/scsi-next: [PATCH] block/iscsi: bump year in copyright notice block/iscsi: allow cluster_size of 4K and greater block/iscsi: clarify the meaning of ISCSI_CHECKALLOC_THRES block/iscsi: speed up read for unallocated sectors block/iscsi: allow fall back to WRITE SAME without UNMAP MAINTAINERS: mark megasas as maintained megasas: Add MSI support megasas: Enable MSI-X support megasas: Implement LD_LIST_QUERY scsi: Improve error messages more scsi-disk: Improve error messager if can't get version number Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
6a23082b4e
7 changed files with 313 additions and 132 deletions
|
@ -21,6 +21,7 @@
|
|||
#include "hw/hw.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "hw/pci/msix.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "hw/scsi/scsi.h"
|
||||
|
@ -43,9 +44,11 @@
|
|||
|
||||
#define MEGASAS_FLAG_USE_JBOD 0
|
||||
#define MEGASAS_MASK_USE_JBOD (1 << MEGASAS_FLAG_USE_JBOD)
|
||||
#define MEGASAS_FLAG_USE_MSIX 1
|
||||
#define MEGASAS_FLAG_USE_MSI 1
|
||||
#define MEGASAS_MASK_USE_MSI (1 << MEGASAS_FLAG_USE_MSI)
|
||||
#define MEGASAS_FLAG_USE_MSIX 2
|
||||
#define MEGASAS_MASK_USE_MSIX (1 << MEGASAS_FLAG_USE_MSIX)
|
||||
#define MEGASAS_FLAG_USE_QUEUE64 2
|
||||
#define MEGASAS_FLAG_USE_QUEUE64 3
|
||||
#define MEGASAS_MASK_USE_QUEUE64 (1 << MEGASAS_FLAG_USE_QUEUE64)
|
||||
|
||||
static const char *mfi_frame_desc[] = {
|
||||
|
@ -132,6 +135,11 @@ static bool megasas_use_queue64(MegasasState *s)
|
|||
return s->flags & MEGASAS_MASK_USE_QUEUE64;
|
||||
}
|
||||
|
||||
static bool megasas_use_msi(MegasasState *s)
|
||||
{
|
||||
return s->flags & MEGASAS_MASK_USE_MSI;
|
||||
}
|
||||
|
||||
static bool megasas_use_msix(MegasasState *s)
|
||||
{
|
||||
return s->flags & MEGASAS_MASK_USE_MSIX;
|
||||
|
@ -538,6 +546,9 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context)
|
|||
if (msix_enabled(pci_dev)) {
|
||||
trace_megasas_msix_raise(0);
|
||||
msix_notify(pci_dev, 0);
|
||||
} else if (msi_enabled(pci_dev)) {
|
||||
trace_megasas_msi_raise(0);
|
||||
msi_notify(pci_dev, 0);
|
||||
} else {
|
||||
trace_megasas_irq_raise();
|
||||
pci_irq_assert(pci_dev);
|
||||
|
@ -1106,6 +1117,21 @@ static int megasas_dcmd_ld_get_list(MegasasState *s, MegasasCmd *cmd)
|
|||
return MFI_STAT_OK;
|
||||
}
|
||||
|
||||
static int megasas_dcmd_ld_list_query(MegasasState *s, MegasasCmd *cmd)
|
||||
{
|
||||
uint16_t flags;
|
||||
|
||||
/* mbox0 contains flags */
|
||||
flags = le16_to_cpu(cmd->frame->dcmd.mbox[0]);
|
||||
trace_megasas_dcmd_ld_list_query(cmd->index, flags);
|
||||
if (flags == MR_LD_QUERY_TYPE_ALL ||
|
||||
flags == MR_LD_QUERY_TYPE_EXPOSED_TO_HOST) {
|
||||
return megasas_dcmd_ld_get_list(s, cmd);
|
||||
}
|
||||
|
||||
return MFI_STAT_OK;
|
||||
}
|
||||
|
||||
static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
|
||||
MegasasCmd *cmd)
|
||||
{
|
||||
|
@ -1409,6 +1435,8 @@ static const struct dcmd_cmd_tbl_t {
|
|||
megasas_dcmd_dummy },
|
||||
{ MFI_DCMD_LD_GET_LIST, "LD_GET_LIST",
|
||||
megasas_dcmd_ld_get_list},
|
||||
{ MFI_DCMD_LD_LIST_QUERY, "LD_LIST_QUERY",
|
||||
megasas_dcmd_ld_list_query },
|
||||
{ MFI_DCMD_LD_GET_INFO, "LD_GET_INFO",
|
||||
megasas_dcmd_ld_get_info },
|
||||
{ MFI_DCMD_LD_GET_PROP, "LD_GET_PROP",
|
||||
|
@ -1939,12 +1967,20 @@ static void megasas_mmio_write(void *opaque, hwaddr addr,
|
|||
break;
|
||||
case MFI_OMSK:
|
||||
s->intr_mask = val;
|
||||
if (!megasas_intr_enabled(s) && !msix_enabled(pci_dev)) {
|
||||
if (!megasas_intr_enabled(s) &&
|
||||
!msi_enabled(pci_dev) &&
|
||||
!msix_enabled(pci_dev)) {
|
||||
trace_megasas_irq_lower();
|
||||
pci_irq_deassert(pci_dev);
|
||||
}
|
||||
if (megasas_intr_enabled(s)) {
|
||||
trace_megasas_intr_enabled();
|
||||
if (msix_enabled(pci_dev)) {
|
||||
trace_megasas_msix_enabled(0);
|
||||
} else if (msi_enabled(pci_dev)) {
|
||||
trace_megasas_msi_enabled(0);
|
||||
} else {
|
||||
trace_megasas_intr_enabled();
|
||||
}
|
||||
} else {
|
||||
trace_megasas_intr_disabled();
|
||||
}
|
||||
|
@ -2068,6 +2104,7 @@ static const VMStateDescription vmstate_megasas = {
|
|||
.minimum_version_id_old = 0,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_PCI_DEVICE(parent_obj, MegasasState),
|
||||
VMSTATE_MSIX(parent_obj, MegasasState),
|
||||
|
||||
VMSTATE_INT32(fw_state, MegasasState),
|
||||
VMSTATE_INT32(intr_mask, MegasasState),
|
||||
|
@ -2083,9 +2120,12 @@ static void megasas_scsi_uninit(PCIDevice *d)
|
|||
{
|
||||
MegasasState *s = MEGASAS(d);
|
||||
|
||||
#ifdef USE_MSIX
|
||||
msix_uninit(d, &s->mmio_io);
|
||||
#endif
|
||||
if (megasas_use_msix(s)) {
|
||||
msix_uninit(d, &s->mmio_io, &s->mmio_io);
|
||||
}
|
||||
if (megasas_use_msi(s)) {
|
||||
msi_uninit(d);
|
||||
}
|
||||
memory_region_destroy(&s->mmio_io);
|
||||
memory_region_destroy(&s->port_io);
|
||||
memory_region_destroy(&s->queue_io);
|
||||
|
@ -2124,15 +2164,15 @@ static int megasas_scsi_init(PCIDevice *dev)
|
|||
memory_region_init_io(&s->queue_io, OBJECT(s), &megasas_queue_ops, s,
|
||||
"megasas-queue", 0x40000);
|
||||
|
||||
#ifdef USE_MSIX
|
||||
/* MSI-X support is currently broken */
|
||||
if (megasas_use_msi(s) &&
|
||||
msi_init(dev, 0x50, 1, true, false)) {
|
||||
s->flags &= ~MEGASAS_MASK_USE_MSI;
|
||||
}
|
||||
if (megasas_use_msix(s) &&
|
||||
msix_init(dev, 15, &s->mmio_io, 0, 0x2000)) {
|
||||
msix_init(dev, 15, &s->mmio_io, 0, 0x2000,
|
||||
&s->mmio_io, 0, 0x3800, 0x68)) {
|
||||
s->flags &= ~MEGASAS_MASK_USE_MSIX;
|
||||
}
|
||||
#else
|
||||
s->flags &= ~MEGASAS_MASK_USE_MSIX;
|
||||
#endif
|
||||
|
||||
bar_type = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64;
|
||||
pci_register_bar(dev, 0, bar_type, &s->mmio_io);
|
||||
|
@ -2151,7 +2191,7 @@ static int megasas_scsi_init(PCIDevice *dev)
|
|||
s->sas_addr |= PCI_FUNC(dev->devfn);
|
||||
}
|
||||
if (!s->hba_serial) {
|
||||
s->hba_serial = g_strdup(MEGASAS_HBA_SERIAL);
|
||||
s->hba_serial = g_strdup(MEGASAS_HBA_SERIAL);
|
||||
}
|
||||
if (s->fw_sge >= MEGASAS_MAX_SGE - MFI_PASS_FRAME_SIZE) {
|
||||
s->fw_sge = MEGASAS_MAX_SGE - MFI_PASS_FRAME_SIZE;
|
||||
|
@ -2164,7 +2204,6 @@ static int megasas_scsi_init(PCIDevice *dev)
|
|||
s->fw_cmds = MEGASAS_MAX_FRAMES;
|
||||
}
|
||||
trace_megasas_init(s->fw_sge, s->fw_cmds,
|
||||
megasas_use_msix(s) ? "MSI-X" : "INTx",
|
||||
megasas_is_jbod(s) ? "jbod" : "raid");
|
||||
s->fw_luns = (MFI_MAX_LD > MAX_SCSI_DEVS) ?
|
||||
MAX_SCSI_DEVS : MFI_MAX_LD;
|
||||
|
@ -2189,6 +2228,13 @@ static int megasas_scsi_init(PCIDevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
megasas_write_config(PCIDevice *pci, uint32_t addr, uint32_t val, int len)
|
||||
{
|
||||
pci_default_write_config(pci, addr, val, len);
|
||||
msi_write_config(pci, addr, val, len);
|
||||
}
|
||||
|
||||
static Property megasas_properties[] = {
|
||||
DEFINE_PROP_UINT32("max_sge", MegasasState, fw_sge,
|
||||
MEGASAS_DEFAULT_SGE),
|
||||
|
@ -2196,10 +2242,10 @@ static Property megasas_properties[] = {
|
|||
MEGASAS_DEFAULT_FRAMES),
|
||||
DEFINE_PROP_STRING("hba_serial", MegasasState, hba_serial),
|
||||
DEFINE_PROP_UINT64("sas_address", MegasasState, sas_addr, 0),
|
||||
#ifdef USE_MSIX
|
||||
DEFINE_PROP_BIT("use_msi", MegasasState, flags,
|
||||
MEGASAS_FLAG_USE_MSI, false),
|
||||
DEFINE_PROP_BIT("use_msix", MegasasState, flags,
|
||||
MEGASAS_FLAG_USE_MSIX, false),
|
||||
#endif
|
||||
DEFINE_PROP_BIT("use_jbod", MegasasState, flags,
|
||||
MEGASAS_FLAG_USE_JBOD, false),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
|
@ -2222,6 +2268,7 @@ static void megasas_class_init(ObjectClass *oc, void *data)
|
|||
dc->vmsd = &vmstate_megasas;
|
||||
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
|
||||
dc->desc = "LSI MegaRAID SAS 1078";
|
||||
pc->config_write = megasas_write_config;
|
||||
}
|
||||
|
||||
static const TypeInfo megasas_info = {
|
||||
|
|
|
@ -164,6 +164,7 @@ typedef enum {
|
|||
MFI_DCMD_PD_BLINK = 0x02070100,
|
||||
MFI_DCMD_PD_UNBLINK = 0x02070200,
|
||||
MFI_DCMD_LD_GET_LIST = 0x03010000,
|
||||
MFI_DCMD_LD_LIST_QUERY = 0x03010100,
|
||||
MFI_DCMD_LD_GET_INFO = 0x03020000,
|
||||
MFI_DCMD_LD_GET_PROP = 0x03030000,
|
||||
MFI_DCMD_LD_SET_PROP = 0x03040000,
|
||||
|
@ -411,6 +412,14 @@ typedef enum {
|
|||
MR_PD_QUERY_TYPE_EXPOSED_TO_HOST = 5, /*query for system drives */
|
||||
} mfi_pd_query_type;
|
||||
|
||||
typedef enum {
|
||||
MR_LD_QUERY_TYPE_ALL = 0,
|
||||
MR_LD_QUERY_TYPE_EXPOSED_TO_HOST = 1,
|
||||
MR_LD_QUERY_TYPE_USED_TGT_IDS = 2,
|
||||
MR_LD_QUERY_TYPE_CLUSTER_ACCESS = 3,
|
||||
MR_LD_QUERY_TYPE_CLUSTER_LOCALE = 4,
|
||||
} mfi_ld_query_type;
|
||||
|
||||
/*
|
||||
* Other propertities and definitions
|
||||
*/
|
||||
|
|
|
@ -2458,21 +2458,27 @@ static int scsi_block_initfn(SCSIDevice *dev)
|
|||
int rc;
|
||||
|
||||
if (!s->qdev.conf.bs) {
|
||||
error_report("scsi-block: drive property not set");
|
||||
error_report("drive property not set");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check we are using a driver managing SG_IO (version 3 and after) */
|
||||
if (bdrv_ioctl(s->qdev.conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
|
||||
sg_version < 30000) {
|
||||
error_report("scsi-block: scsi generic interface too old");
|
||||
rc = bdrv_ioctl(s->qdev.conf.bs, SG_GET_VERSION_NUM, &sg_version);
|
||||
if (rc < 0) {
|
||||
error_report("cannot get SG_IO version number: %s. "
|
||||
"Is this a SCSI device?",
|
||||
strerror(-rc));
|
||||
return -1;
|
||||
}
|
||||
if (sg_version < 30000) {
|
||||
error_report("scsi generic interface too old");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get device type from INQUIRY data */
|
||||
rc = get_device_type(s);
|
||||
if (rc < 0) {
|
||||
error_report("scsi-block: INQUIRY failed");
|
||||
error_report("INQUIRY failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -394,6 +394,7 @@ static void scsi_destroy(SCSIDevice *s)
|
|||
|
||||
static int scsi_generic_initfn(SCSIDevice *s)
|
||||
{
|
||||
int rc;
|
||||
int sg_version;
|
||||
struct sg_scsi_id scsiid;
|
||||
|
||||
|
@ -412,8 +413,11 @@ static int scsi_generic_initfn(SCSIDevice *s)
|
|||
}
|
||||
|
||||
/* check we are using a driver managing SG_IO (version 3 and after */
|
||||
if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0) {
|
||||
error_report("scsi generic interface not supported");
|
||||
rc = bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version);
|
||||
if (rc < 0) {
|
||||
error_report("cannot get SG_IO version number: %s. "
|
||||
"Is this a SCSI device?",
|
||||
strerror(-rc));
|
||||
return -1;
|
||||
}
|
||||
if (sg_version < 30000) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue