static int megasas_scsi_init(PCIDevice *dev)

{

    DeviceState *d = DEVICE(dev);

    MegasasState *s = MEGASAS(dev);

    MegasasBaseClass *b = MEGASAS_DEVICE_GET_CLASS(s);

    uint8_t *pci_conf;

    int i, bar_type;

    Error *err = NULL;



    pci_conf = dev->config;



    /* PCI latency timer = 0 */

    pci_conf[PCI_LATENCY_TIMER] = 0;

    /* Interrupt pin 1 */

    pci_conf[PCI_INTERRUPT_PIN] = 0x01;



    memory_region_init_io(&s->mmio_io, OBJECT(s), &megasas_mmio_ops, s,

                          "megasas-mmio", 0x4000);

    memory_region_init_io(&s->port_io, OBJECT(s), &megasas_port_ops, s,

                          "megasas-io", 256);

    memory_region_init_io(&s->queue_io, OBJECT(s), &megasas_queue_ops, s,

                          "megasas-queue", 0x40000);



    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, b->mmio_bar, 0x2000,

                  &s->mmio_io, b->mmio_bar, 0x3800, 0x68)) {

        s->flags &= ~MEGASAS_MASK_USE_MSIX;

    }

    if (pci_is_express(dev)) {

        pcie_endpoint_cap_init(dev, 0xa0);

    }



    bar_type = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64;

    pci_register_bar(dev, b->ioport_bar,

                     PCI_BASE_ADDRESS_SPACE_IO, &s->port_io);

    pci_register_bar(dev, b->mmio_bar, bar_type, &s->mmio_io);

    pci_register_bar(dev, 3, bar_type, &s->queue_io);



    if (megasas_use_msix(s)) {

        msix_vector_use(dev, 0);

    }



    s->fw_state = MFI_FWSTATE_READY;

    if (!s->sas_addr) {

        s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |

                       IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;

        s->sas_addr |= (pci_bus_num(dev->bus) << 16);

        s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);

        s->sas_addr |= PCI_FUNC(dev->devfn);

    }

    if (!s->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;

    } else if (s->fw_sge >= 128 - MFI_PASS_FRAME_SIZE) {

        s->fw_sge = 128 - MFI_PASS_FRAME_SIZE;

    } else {

        s->fw_sge = 64 - MFI_PASS_FRAME_SIZE;

    }

    if (s->fw_cmds > MEGASAS_MAX_FRAMES) {

        s->fw_cmds = MEGASAS_MAX_FRAMES;

    }

    trace_megasas_init(s->fw_sge, s->fw_cmds,

                       megasas_is_jbod(s) ? "jbod" : "raid");



    if (megasas_is_jbod(s)) {

        s->fw_luns = MFI_MAX_SYS_PDS;

    } else {

        s->fw_luns = MFI_MAX_LD;

    }

    s->producer_pa = 0;

    s->consumer_pa = 0;

    for (i = 0; i < s->fw_cmds; i++) {

        s->frames[i].index = i;

        s->frames[i].context = -1;

        s->frames[i].pa = 0;

        s->frames[i].state = s;

    }



    scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),

                 &megasas_scsi_info, NULL);

    if (!d->hotplugged) {

        scsi_bus_legacy_handle_cmdline(&s->bus, &err);

        if (err != NULL) {


            error_free(err);

            return -1;

        }

    }

    return 0;

}