diff options
author | RajithaY <rajithax.yerrumsetty@intel.com> | 2017-04-25 03:31:15 -0700 |
---|---|---|
committer | Rajitha Yerrumchetty <rajithax.yerrumsetty@intel.com> | 2017-05-22 06:48:08 +0000 |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/hw/scsi/mptconfig.c | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/hw/scsi/mptconfig.c')
-rw-r--r-- | qemu/hw/scsi/mptconfig.c | 905 |
1 files changed, 0 insertions, 905 deletions
diff --git a/qemu/hw/scsi/mptconfig.c b/qemu/hw/scsi/mptconfig.c deleted file mode 100644 index 707185469..000000000 --- a/qemu/hw/scsi/mptconfig.c +++ /dev/null @@ -1,905 +0,0 @@ -/* - * QEMU LSI SAS1068 Host Bus Adapter emulation - configuration pages - * - * Copyright (c) 2016 Red Hat, Inc. - * - * Author: Paolo Bonzini - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -#include "qemu/osdep.h" -#include "hw/hw.h" -#include "hw/pci/pci.h" -#include "hw/scsi/scsi.h" - -#include "mptsas.h" -#include "mpi.h" -#include "trace.h" - -/* Generic functions for marshaling and unmarshaling. */ - -#define repl1(x) x -#define repl2(x) x x -#define repl3(x) x x x -#define repl4(x) x x x x -#define repl5(x) x x x x x -#define repl6(x) x x x x x x -#define repl7(x) x x x x x x x -#define repl8(x) x x x x x x x x - -#define repl(n, x) glue(repl, n)(x) - -typedef union PackValue { - uint64_t ll; - char *str; -} PackValue; - -static size_t vfill(uint8_t *data, size_t size, const char *fmt, va_list ap) -{ - size_t ofs; - PackValue val; - const char *p; - - ofs = 0; - p = fmt; - while (*p) { - memset(&val, 0, sizeof(val)); - switch (*p) { - case '*': - p++; - break; - case 'b': - case 'w': - case 'l': - val.ll = va_arg(ap, int); - break; - case 'q': - val.ll = va_arg(ap, int64_t); - break; - case 's': - val.str = va_arg(ap, void *); - break; - } - switch (*p++) { - case 'b': - if (data) { - stb_p(data + ofs, val.ll); - } - ofs++; - break; - case 'w': - if (data) { - stw_le_p(data + ofs, val.ll); - } - ofs += 2; - break; - case 'l': - if (data) { - stl_le_p(data + ofs, val.ll); - } - ofs += 4; - break; - case 'q': - if (data) { - stq_le_p(data + ofs, val.ll); - } - ofs += 8; - break; - case 's': - { - int cnt = atoi(p); - if (data) { - if (val.str) { - strncpy((void *)data + ofs, val.str, cnt); - } else { - memset((void *)data + ofs, 0, cnt); - } - } - ofs += cnt; - break; - } - } - } - - return ofs; -} - -static size_t vpack(uint8_t **p_data, const char *fmt, va_list ap1) -{ - size_t size = 0; - uint8_t *data = NULL; - - if (p_data) { - va_list ap2; - - va_copy(ap2, ap1); - size = vfill(NULL, 0, fmt, ap2); - *p_data = data = g_malloc(size); - va_end(ap2); - } - return vfill(data, size, fmt, ap1); -} - -static size_t fill(uint8_t *data, size_t size, const char *fmt, ...) -{ - va_list ap; - size_t ret; - - va_start(ap, fmt); - ret = vfill(data, size, fmt, ap); - va_end(ap); - - return ret; -} - -/* Functions to build the page header and fill in the length, always used - * through the macros. - */ - -#define MPTSAS_CONFIG_PACK(number, type, version, fmt, ...) \ - mptsas_config_pack(data, "b*bbb" fmt, version, number, type, \ - ## __VA_ARGS__) - -static size_t mptsas_config_pack(uint8_t **data, const char *fmt, ...) -{ - va_list ap; - size_t ret; - - va_start(ap, fmt); - ret = vpack(data, fmt, ap); - va_end(ap); - - if (data) { - assert(ret < 256 && (ret % 4) == 0); - stb_p(*data + 1, ret / 4); - } - return ret; -} - -#define MPTSAS_CONFIG_PACK_EXT(number, type, version, fmt, ...) \ - mptsas_config_pack_ext(data, "b*bbb*wb*b" fmt, version, number, \ - MPI_CONFIG_PAGETYPE_EXTENDED, type, ## __VA_ARGS__) - -static size_t mptsas_config_pack_ext(uint8_t **data, const char *fmt, ...) -{ - va_list ap; - size_t ret; - - va_start(ap, fmt); - ret = vpack(data, fmt, ap); - va_end(ap); - - if (data) { - assert(ret < 65536 && (ret % 4) == 0); - stw_le_p(*data + 4, ret / 4); - } - return ret; -} - -/* Manufacturing pages */ - -static -size_t mptsas_config_manufacturing_0(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(0, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00, - "s16s8s16s16s16", - "QEMU MPT Fusion", - "2.5", - "QEMU MPT Fusion", - "QEMU", - "0000111122223333"); -} - -static -size_t mptsas_config_manufacturing_1(MPTSASState *s, uint8_t **data, int address) -{ - /* VPD - all zeros */ - return MPTSAS_CONFIG_PACK(1, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00, - "s256"); -} - -static -size_t mptsas_config_manufacturing_2(MPTSASState *s, uint8_t **data, int address) -{ - PCIDeviceClass *pcic = PCI_DEVICE_GET_CLASS(s); - return MPTSAS_CONFIG_PACK(2, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00, - "wb*b*l", - pcic->device_id, pcic->revision); -} - -static -size_t mptsas_config_manufacturing_3(MPTSASState *s, uint8_t **data, int address) -{ - PCIDeviceClass *pcic = PCI_DEVICE_GET_CLASS(s); - return MPTSAS_CONFIG_PACK(3, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00, - "wb*b*l", - pcic->device_id, pcic->revision); -} - -static -size_t mptsas_config_manufacturing_4(MPTSASState *s, uint8_t **data, int address) -{ - /* All zeros */ - return MPTSAS_CONFIG_PACK(4, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x05, - "*l*b*b*b*b*b*b*w*s56*l*l*l*l*l*l" - "*b*b*w*b*b*w*l*l"); -} - -static -size_t mptsas_config_manufacturing_5(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(5, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x02, - "q*b*b*w*l*l", s->sas_addr); -} - -static -size_t mptsas_config_manufacturing_6(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(6, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00, - "*l"); -} - -static -size_t mptsas_config_manufacturing_7(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(7, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00, - "*l*l*l*s16*b*b*w", MPTSAS_NUM_PORTS); -} - -static -size_t mptsas_config_manufacturing_8(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(8, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00, - "*l"); -} - -static -size_t mptsas_config_manufacturing_9(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(9, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00, - "*l"); -} - -static -size_t mptsas_config_manufacturing_10(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(10, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00, - "*l"); -} - -/* I/O unit pages */ - -static -size_t mptsas_config_io_unit_0(MPTSASState *s, uint8_t **data, int address) -{ - PCIDevice *pci = PCI_DEVICE(s); - uint64_t unique_value = 0x53504D554D4551LL; /* "QEMUMPTx" */ - - unique_value |= (uint64_t)pci->devfn << 56; - return MPTSAS_CONFIG_PACK(0, MPI_CONFIG_PAGETYPE_IO_UNIT, 0x00, - "q", unique_value); -} - -static -size_t mptsas_config_io_unit_1(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(1, MPI_CONFIG_PAGETYPE_IO_UNIT, 0x02, "l", - 0x41 /* single function, RAID disabled */ ); -} - -static -size_t mptsas_config_io_unit_2(MPTSASState *s, uint8_t **data, int address) -{ - PCIDevice *pci = PCI_DEVICE(s); - uint8_t devfn = pci->devfn; - return MPTSAS_CONFIG_PACK(2, MPI_CONFIG_PAGETYPE_IO_UNIT, 0x02, - "llbbw*b*b*w*b*b*w*b*b*w*l", - 0, 0x100, 0 /* pci bus? */, devfn, 0); -} - -static -size_t mptsas_config_io_unit_3(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(3, MPI_CONFIG_PAGETYPE_IO_UNIT, 0x01, - "*b*b*w*l"); -} - -static -size_t mptsas_config_io_unit_4(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(4, MPI_CONFIG_PAGETYPE_IO_UNIT, 0x00, "*l*l*q"); -} - -/* I/O controller pages */ - -static -size_t mptsas_config_ioc_0(MPTSASState *s, uint8_t **data, int address) -{ - PCIDeviceClass *pcic = PCI_DEVICE_GET_CLASS(s); - - return MPTSAS_CONFIG_PACK(0, MPI_CONFIG_PAGETYPE_IOC, 0x01, - "*l*lwwb*b*b*blww", - pcic->vendor_id, pcic->device_id, pcic->revision, - pcic->subsystem_vendor_id, - pcic->subsystem_id); -} - -static -size_t mptsas_config_ioc_1(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(1, MPI_CONFIG_PAGETYPE_IOC, 0x03, - "*l*l*b*b*b*b"); -} - -static -size_t mptsas_config_ioc_2(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(2, MPI_CONFIG_PAGETYPE_IOC, 0x04, - "*l*b*b*b*b"); -} - -static -size_t mptsas_config_ioc_3(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(3, MPI_CONFIG_PAGETYPE_IOC, 0x00, - "*b*b*w"); -} - -static -size_t mptsas_config_ioc_4(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(4, MPI_CONFIG_PAGETYPE_IOC, 0x00, - "*b*b*w"); -} - -static -size_t mptsas_config_ioc_5(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(5, MPI_CONFIG_PAGETYPE_IOC, 0x00, - "*l*b*b*w"); -} - -static -size_t mptsas_config_ioc_6(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK(6, MPI_CONFIG_PAGETYPE_IOC, 0x01, - "*l*b*b*b*b*b*b*b*b*b*b*w*l*l*l*l*b*b*w" - "*w*w*w*w*l*l*l"); -} - -/* SAS I/O unit pages (extended) */ - -#define MPTSAS_CONFIG_SAS_IO_UNIT_0_SIZE 16 - -#define MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION 0x02 -#define MPI_SAS_IOUNIT0_RATE_1_5 0x08 -#define MPI_SAS_IOUNIT0_RATE_3_0 0x09 - -#define MPI_SAS_DEVICE_INFO_NO_DEVICE 0x00000000 -#define MPI_SAS_DEVICE_INFO_END_DEVICE 0x00000001 -#define MPI_SAS_DEVICE_INFO_SSP_TARGET 0x00000400 - -#define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS 0x00 - -#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT 0x0001 -#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED 0x0002 -#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT 0x0004 - - - -static SCSIDevice *mptsas_phy_get_device(MPTSASState *s, int i, - int *phy_handle, int *dev_handle) -{ - SCSIDevice *d = scsi_device_find(&s->bus, 0, i, 0); - - if (phy_handle) { - *phy_handle = i + 1; - } - if (dev_handle) { - *dev_handle = d ? i + 1 + MPTSAS_NUM_PORTS : 0; - } - return d; -} - -static -size_t mptsas_config_sas_io_unit_0(MPTSASState *s, uint8_t **data, int address) -{ - size_t size = MPTSAS_CONFIG_PACK_EXT(0, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0x04, - "*w*wb*b*w" - repl(MPTSAS_NUM_PORTS, "*s16"), - MPTSAS_NUM_PORTS); - - if (data) { - size_t ofs = size - MPTSAS_NUM_PORTS * MPTSAS_CONFIG_SAS_IO_UNIT_0_SIZE; - int i; - - for (i = 0; i < MPTSAS_NUM_PORTS; i++) { - int phy_handle, dev_handle; - SCSIDevice *dev = mptsas_phy_get_device(s, i, &phy_handle, &dev_handle); - - fill(*data + ofs, MPTSAS_CONFIG_SAS_IO_UNIT_0_SIZE, - "bbbblwwl", i, 0, 0, - (dev - ? MPI_SAS_IOUNIT0_RATE_3_0 - : MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION), - (dev - ? MPI_SAS_DEVICE_INFO_END_DEVICE | MPI_SAS_DEVICE_INFO_SSP_TARGET - : MPI_SAS_DEVICE_INFO_NO_DEVICE), - dev_handle, - dev_handle, - 0); - ofs += MPTSAS_CONFIG_SAS_IO_UNIT_0_SIZE; - } - assert(ofs == size); - } - return size; -} - -#define MPTSAS_CONFIG_SAS_IO_UNIT_1_SIZE 12 - -static -size_t mptsas_config_sas_io_unit_1(MPTSASState *s, uint8_t **data, int address) -{ - size_t size = MPTSAS_CONFIG_PACK_EXT(1, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0x07, - "*w*w*w*wb*b*b*b" - repl(MPTSAS_NUM_PORTS, "*s12"), - MPTSAS_NUM_PORTS); - - if (data) { - size_t ofs = size - MPTSAS_NUM_PORTS * MPTSAS_CONFIG_SAS_IO_UNIT_1_SIZE; - int i; - - for (i = 0; i < MPTSAS_NUM_PORTS; i++) { - SCSIDevice *dev = mptsas_phy_get_device(s, i, NULL, NULL); - fill(*data + ofs, MPTSAS_CONFIG_SAS_IO_UNIT_1_SIZE, - "bbbblww", i, 0, 0, - (MPI_SAS_IOUNIT0_RATE_3_0 << 4) | MPI_SAS_IOUNIT0_RATE_1_5, - (dev - ? MPI_SAS_DEVICE_INFO_END_DEVICE | MPI_SAS_DEVICE_INFO_SSP_TARGET - : MPI_SAS_DEVICE_INFO_NO_DEVICE), - 0, 0); - ofs += MPTSAS_CONFIG_SAS_IO_UNIT_1_SIZE; - } - assert(ofs == size); - } - return size; -} - -static -size_t mptsas_config_sas_io_unit_2(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK_EXT(2, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0x06, - "*b*b*w*w*w*b*b*w"); -} - -static -size_t mptsas_config_sas_io_unit_3(MPTSASState *s, uint8_t **data, int address) -{ - return MPTSAS_CONFIG_PACK_EXT(3, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0x06, - "*l*l*l*l*l*l*l*l*l"); -} - -/* SAS PHY pages (extended) */ - -static int mptsas_phy_addr_get(MPTSASState *s, int address) -{ - int i; - if ((address >> MPI_SAS_PHY_PGAD_FORM_SHIFT) == 0) { - i = address & 255; - } else if ((address >> MPI_SAS_PHY_PGAD_FORM_SHIFT) == 1) { - i = address & 65535; - } else { - return -EINVAL; - } - - if (i >= MPTSAS_NUM_PORTS) { - return -EINVAL; - } - - return i; -} - -static -size_t mptsas_config_phy_0(MPTSASState *s, uint8_t **data, int address) -{ - int phy_handle = -1; - int dev_handle = -1; - int i = mptsas_phy_addr_get(s, address); - SCSIDevice *dev; - - if (i < 0) { - trace_mptsas_config_sas_phy(s, address, i, phy_handle, dev_handle, 0); - return i; - } - - dev = mptsas_phy_get_device(s, i, &phy_handle, &dev_handle); - trace_mptsas_config_sas_phy(s, address, i, phy_handle, dev_handle, 0); - - return MPTSAS_CONFIG_PACK_EXT(0, MPI_CONFIG_EXTPAGETYPE_SAS_PHY, 0x01, - "w*wqwb*blbb*b*b*l", - dev_handle, s->sas_addr, dev_handle, i, - (dev - ? MPI_SAS_DEVICE_INFO_END_DEVICE /* | MPI_SAS_DEVICE_INFO_SSP_TARGET?? */ - : MPI_SAS_DEVICE_INFO_NO_DEVICE), - (MPI_SAS_IOUNIT0_RATE_3_0 << 4) | MPI_SAS_IOUNIT0_RATE_1_5, - (MPI_SAS_IOUNIT0_RATE_3_0 << 4) | MPI_SAS_IOUNIT0_RATE_1_5); -} - -static -size_t mptsas_config_phy_1(MPTSASState *s, uint8_t **data, int address) -{ - int phy_handle = -1; - int dev_handle = -1; - int i = mptsas_phy_addr_get(s, address); - - if (i < 0) { - trace_mptsas_config_sas_phy(s, address, i, phy_handle, dev_handle, 1); - return i; - } - - (void) mptsas_phy_get_device(s, i, &phy_handle, &dev_handle); - trace_mptsas_config_sas_phy(s, address, i, phy_handle, dev_handle, 1); - - return MPTSAS_CONFIG_PACK_EXT(1, MPI_CONFIG_EXTPAGETYPE_SAS_PHY, 0x01, - "*l*l*l*l*l"); -} - -/* SAS device pages (extended) */ - -static int mptsas_device_addr_get(MPTSASState *s, int address) -{ - uint32_t handle, i; - uint32_t form = address >> MPI_SAS_PHY_PGAD_FORM_SHIFT; - if (form == MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE) { - handle = address & MPI_SAS_DEVICE_PGAD_GNH_HANDLE_MASK; - do { - if (handle == 65535) { - handle = MPTSAS_NUM_PORTS + 1; - } else { - ++handle; - } - i = handle - 1 - MPTSAS_NUM_PORTS; - } while (i < MPTSAS_NUM_PORTS && !scsi_device_find(&s->bus, 0, i, 0)); - - } else if (form == MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID) { - if (address & MPI_SAS_DEVICE_PGAD_BT_BUS_MASK) { - return -EINVAL; - } - i = address & MPI_SAS_DEVICE_PGAD_BT_TID_MASK; - - } else if (form == MPI_SAS_DEVICE_PGAD_FORM_HANDLE) { - handle = address & MPI_SAS_DEVICE_PGAD_H_HANDLE_MASK; - i = handle - 1 - MPTSAS_NUM_PORTS; - - } else { - return -EINVAL; - } - - if (i >= MPTSAS_NUM_PORTS) { - return -EINVAL; - } - - return i; -} - -static -size_t mptsas_config_sas_device_0(MPTSASState *s, uint8_t **data, int address) -{ - int phy_handle = -1; - int dev_handle = -1; - int i = mptsas_device_addr_get(s, address); - SCSIDevice *dev = mptsas_phy_get_device(s, i, &phy_handle, &dev_handle); - - trace_mptsas_config_sas_device(s, address, i, phy_handle, dev_handle, 0); - if (!dev) { - return -ENOENT; - } - - return MPTSAS_CONFIG_PACK_EXT(0, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0x05, - "*w*wqwbbwbblwb*b", - dev->wwn, phy_handle, i, - MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS, - dev_handle, i, 0, - MPI_SAS_DEVICE_INFO_END_DEVICE | MPI_SAS_DEVICE_INFO_SSP_TARGET, - (MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT | - MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED | - MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT), i); -} - -static -size_t mptsas_config_sas_device_1(MPTSASState *s, uint8_t **data, int address) -{ - int phy_handle = -1; - int dev_handle = -1; - int i = mptsas_device_addr_get(s, address); - SCSIDevice *dev = mptsas_phy_get_device(s, i, &phy_handle, &dev_handle); - - trace_mptsas_config_sas_device(s, address, i, phy_handle, dev_handle, 1); - if (!dev) { - return -ENOENT; - } - - return MPTSAS_CONFIG_PACK_EXT(1, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0x00, - "*lq*lwbb*s20", - dev->wwn, dev_handle, i, 0); -} - -static -size_t mptsas_config_sas_device_2(MPTSASState *s, uint8_t **data, int address) -{ - int phy_handle = -1; - int dev_handle = -1; - int i = mptsas_device_addr_get(s, address); - SCSIDevice *dev = mptsas_phy_get_device(s, i, &phy_handle, &dev_handle); - - trace_mptsas_config_sas_device(s, address, i, phy_handle, dev_handle, 2); - if (!dev) { - return -ENOENT; - } - - return MPTSAS_CONFIG_PACK_EXT(2, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0x01, - "ql", dev->wwn, 0); -} - -typedef struct MPTSASConfigPage { - uint8_t number; - uint8_t type; - size_t (*mpt_config_build)(MPTSASState *s, uint8_t **data, int address); -} MPTSASConfigPage; - -static const MPTSASConfigPage mptsas_config_pages[] = { - { - 0, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_0, - }, { - 1, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_1, - }, { - 2, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_2, - }, { - 3, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_3, - }, { - 4, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_4, - }, { - 5, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_5, - }, { - 6, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_6, - }, { - 7, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_7, - }, { - 8, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_8, - }, { - 9, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_9, - }, { - 10, MPI_CONFIG_PAGETYPE_MANUFACTURING, - mptsas_config_manufacturing_10, - }, { - 0, MPI_CONFIG_PAGETYPE_IO_UNIT, - mptsas_config_io_unit_0, - }, { - 1, MPI_CONFIG_PAGETYPE_IO_UNIT, - mptsas_config_io_unit_1, - }, { - 2, MPI_CONFIG_PAGETYPE_IO_UNIT, - mptsas_config_io_unit_2, - }, { - 3, MPI_CONFIG_PAGETYPE_IO_UNIT, - mptsas_config_io_unit_3, - }, { - 4, MPI_CONFIG_PAGETYPE_IO_UNIT, - mptsas_config_io_unit_4, - }, { - 0, MPI_CONFIG_PAGETYPE_IOC, - mptsas_config_ioc_0, - }, { - 1, MPI_CONFIG_PAGETYPE_IOC, - mptsas_config_ioc_1, - }, { - 2, MPI_CONFIG_PAGETYPE_IOC, - mptsas_config_ioc_2, - }, { - 3, MPI_CONFIG_PAGETYPE_IOC, - mptsas_config_ioc_3, - }, { - 4, MPI_CONFIG_PAGETYPE_IOC, - mptsas_config_ioc_4, - }, { - 5, MPI_CONFIG_PAGETYPE_IOC, - mptsas_config_ioc_5, - }, { - 6, MPI_CONFIG_PAGETYPE_IOC, - mptsas_config_ioc_6, - }, { - 0, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, - mptsas_config_sas_io_unit_0, - }, { - 1, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, - mptsas_config_sas_io_unit_1, - }, { - 2, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, - mptsas_config_sas_io_unit_2, - }, { - 3, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, - mptsas_config_sas_io_unit_3, - }, { - 0, MPI_CONFIG_EXTPAGETYPE_SAS_PHY, - mptsas_config_phy_0, - }, { - 1, MPI_CONFIG_EXTPAGETYPE_SAS_PHY, - mptsas_config_phy_1, - }, { - 0, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE, - mptsas_config_sas_device_0, - }, { - 1, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE, - mptsas_config_sas_device_1, - }, { - 2, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE, - mptsas_config_sas_device_2, - } -}; - -static const MPTSASConfigPage *mptsas_find_config_page(int type, int number) -{ - const MPTSASConfigPage *page; - int i; - - for (i = 0; i < ARRAY_SIZE(mptsas_config_pages); i++) { - page = &mptsas_config_pages[i]; - if (page->type == type && page->number == number) { - return page; - } - } - - return NULL; -} - -void mptsas_process_config(MPTSASState *s, MPIMsgConfig *req) -{ - PCIDevice *pci = PCI_DEVICE(s); - - MPIMsgConfigReply reply; - const MPTSASConfigPage *page; - size_t length; - uint8_t type; - uint8_t *data = NULL; - uint32_t flags_and_length; - uint32_t dmalen; - uint64_t pa; - - mptsas_fix_config_endianness(req); - - QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req)); - QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply)); - - /* Copy common bits from the request into the reply. */ - memset(&reply, 0, sizeof(reply)); - reply.Action = req->Action; - reply.Function = req->Function; - reply.MsgContext = req->MsgContext; - reply.MsgLength = sizeof(reply) / 4; - reply.PageType = req->PageType; - reply.PageNumber = req->PageNumber; - reply.PageLength = req->PageLength; - reply.PageVersion = req->PageVersion; - - type = req->PageType & MPI_CONFIG_PAGETYPE_MASK; - if (type == MPI_CONFIG_PAGETYPE_EXTENDED) { - type = req->ExtPageType; - if (type <= MPI_CONFIG_PAGETYPE_MASK) { - reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_TYPE; - goto out; - } - - reply.ExtPageType = req->ExtPageType; - } - - page = mptsas_find_config_page(type, req->PageNumber); - - switch(req->Action) { - case MPI_CONFIG_ACTION_PAGE_DEFAULT: - case MPI_CONFIG_ACTION_PAGE_HEADER: - case MPI_CONFIG_ACTION_PAGE_READ_NVRAM: - case MPI_CONFIG_ACTION_PAGE_READ_CURRENT: - case MPI_CONFIG_ACTION_PAGE_READ_DEFAULT: - case MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT: - case MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM: - break; - - default: - reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_ACTION; - goto out; - } - - if (!page) { - page = mptsas_find_config_page(type, 1); - if (page) { - reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_PAGE; - } else { - reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_TYPE; - } - goto out; - } - - if (req->Action == MPI_CONFIG_ACTION_PAGE_DEFAULT || - req->Action == MPI_CONFIG_ACTION_PAGE_HEADER) { - length = page->mpt_config_build(s, NULL, req->PageAddress); - if ((ssize_t)length < 0) { - reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_PAGE; - goto out; - } else { - goto done; - } - } - - if (req->Action == MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT || - req->Action == MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM) { - length = page->mpt_config_build(s, NULL, req->PageAddress); - if ((ssize_t)length < 0) { - reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_PAGE; - } else { - reply.IOCStatus = MPI_IOCSTATUS_CONFIG_CANT_COMMIT; - } - goto out; - } - - flags_and_length = req->PageBufferSGE.FlagsLength; - dmalen = flags_and_length & MPI_SGE_LENGTH_MASK; - if (dmalen == 0) { - length = page->mpt_config_build(s, NULL, req->PageAddress); - if ((ssize_t)length < 0) { - reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_PAGE; - goto out; - } else { - goto done; - } - } - - if (flags_and_length & MPI_SGE_FLAGS_64_BIT_ADDRESSING) { - pa = req->PageBufferSGE.u.Address64; - } else { - pa = req->PageBufferSGE.u.Address32; - } - - /* Only read actions left. */ - length = page->mpt_config_build(s, &data, req->PageAddress); - if ((ssize_t)length < 0) { - reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_PAGE; - goto out; - } else { - assert(data[2] == page->number); - pci_dma_write(pci, pa, data, MIN(length, dmalen)); - goto done; - } - - abort(); - -done: - if (type > MPI_CONFIG_PAGETYPE_MASK) { - reply.ExtPageLength = length / 4; - reply.ExtPageType = req->ExtPageType; - } else { - reply.PageLength = length / 4; - } - -out: - mptsas_fix_config_reply_endianness(&reply); - mptsas_reply(s, (MPIDefaultReply *)&reply); - g_free(data); -} |