/*
 * 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.1 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/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 / 4 < 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->class_id, 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);
}
