Ticket #9807: 0001-FreeBSD-compat-layer-implement-MSI-X-support.patch

File 0001-FreeBSD-compat-layer-implement-MSI-X-support.patch, 4.8 KB (added by korli, 8 years ago)

freebsd msi-x

  • src/libs/compat/freebsd_network/bus.cpp

    From 872226839cac3c72ed30dc23f5d8b531e365d7cf Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= <jerome.duval@gmail.com>
    Date: Mon, 29 Jul 2013 23:04:45 +0200
    Subject: [PATCH] FreeBSD compat layer: implement MSI-X support.
    
    ---
     src/libs/compat/freebsd_network/bus.cpp  | 61 ++++++++++++++++++++++----------
     src/libs/compat/freebsd_network/device.h |  2 ++
     2 files changed, 45 insertions(+), 18 deletions(-)
    
    diff --git a/src/libs/compat/freebsd_network/bus.cpp b/src/libs/compat/freebsd_network/bus.cpp
    index 22aed56..3353471 100644
    a b struct internal_intr {  
    5656    void            *arg;
    5757    int             irq;
    5858    uint32          flags;
    59     bool            is_msi;
    6059
    6160    thread_id       thread;
    6261    sem_id          sem;
    bus_alloc_resource(device_t dev, int type, int *rid, unsigned long start,  
    170169            res->r_bustag = 1;
    171170            res->r_bushandle = info->u.h0.interrupt_line + *rid - 1;
    172171            result = 0;
    173 
    174             // TODO: msi-x interrupts
    175172        }
    176173    } else if (type == SYS_RES_MEMORY)
    177174        result = bus_alloc_mem_resource(dev, res, *rid);
    bus_setup_intr(device_t dev, struct resource *res, int flags,  
    349346    intr->arg = arg;
    350347    intr->irq = res->r_bushandle;
    351348    intr->flags = flags;
    352     intr->is_msi = false;
    353349    intr->sem = -1;
    354350    intr->thread = -1;
    355351
    bus_setup_intr(device_t dev, struct resource *res, int flags,  
    386382        // this is an msi, enable it
    387383        pci_info *info
    388384            = &((struct root_device_softc *)dev->root->softc)->pci_info;
    389         if (gPCIx86->enable_msi(info->bus, info->device,
    390                 info->function) != B_OK) {
    391             device_printf(dev, "enabling msi failed\n");
    392             bus_teardown_intr(dev, res, intr);
    393             return ENODEV;
     385        if (&((struct root_device_softc *)dev->root->softc)->is_msi) {
     386            if (gPCIx86->enable_msi(info->bus, info->device,
     387                    info->function) != B_OK) {
     388                device_printf(dev, "enabling msi failed\n");
     389                bus_teardown_intr(dev, res, intr);
     390                return ENODEV;
     391            }
     392        } else if (&((struct root_device_softc *)dev->root->softc)->is_msix) {
     393            if (gPCIx86->enable_msix(info->bus, info->device,
     394                    info->function) != B_OK) {
     395                device_printf(dev, "enabling msix failed\n");
     396                bus_teardown_intr(dev, res, intr);
     397                return ENODEV;
     398            }
    394399        }
    395 
    396         intr->is_msi = true;
    397400    }
    398401
    399402    if (status < B_OK) {
    int  
    412415bus_teardown_intr(device_t dev, struct resource *res, void *arg)
    413416{
    414417    struct internal_intr *intr = (struct internal_intr *)arg;
     418    struct root_device_softc *root = (struct root_device_softc *)dev->root->softc;
    415419
    416     if (intr->is_msi && gPCIx86 != NULL) {
     420    if ((root->is_msi || root->is_msix) && gPCIx86 != NULL) {
    417421        // disable msi generation
    418         pci_info *info
    419             = &((struct root_device_softc *)dev->root->softc)->pci_info;
     422        pci_info *info = &root->pci_info;
    420423        gPCIx86->disable_msi(info->bus, info->device, info->function);
    421424    }
    422425
    pci_get_domain(device_t dev)  
    613616    return 0;
    614617}
    615618
    616 uint32_t 
     619uint32_t
    617620pci_get_devid(device_t dev)
    618621{
    619622    return pci_read_config(dev, PCI_device_id, 2) << 16 |
    620623        pci_read_config(dev, PCI_vendor_id, 2);
    621624}
    622625
    623 uint8_t 
     626uint8_t
    624627pci_get_cachelnsz(device_t dev)
    625628{
    626629    return pci_read_config(dev, PCI_line_size, 1);
    pci_alloc_msi(device_t dev, int *count)  
    787790        return ENODEV;
    788791    }
    789792
     793    ((struct root_device_softc *)dev->root->softc)->is_msi = true;
    790794    info->u.h0.interrupt_line = startVector;
    791795    return EOK;
    792796}
    pci_release_msi(device_t dev)  
    801805
    802806    info = &((struct root_device_softc *)dev->root->softc)->pci_info;
    803807    gPCIx86->unconfigure_msi(info->bus, info->device, info->function);
     808    ((struct root_device_softc *)dev->root->softc)->is_msi = false;
     809    ((struct root_device_softc *)dev->root->softc)->is_msix = false;
    804810    return EOK;
    805811}
    806812
    pci_release_msi(device_t dev)  
    808814int
    809815pci_msix_count(device_t dev)
    810816{
    811     return 0;
     817    pci_info *info;
     818    if (gPCIx86 == NULL)
     819        return 0;
     820
     821    info = &((struct root_device_softc *)dev->root->softc)->pci_info;
     822    return gPCIx86->get_msix_count(info->bus, info->device, info->function);
    812823}
    813824
    814825
    815826int
    816827pci_alloc_msix(device_t dev, int *count)
    817828{
    818     return ENODEV;
     829    pci_info *info;
     830    uint8 startVector = 0;
     831    if (gPCIx86 == NULL)
     832        return ENODEV;
     833
     834    info = &((struct root_device_softc *)dev->root->softc)->pci_info;
     835
     836    if (gPCIx86->configure_msix(info->bus, info->device, info->function, *count,
     837            &startVector) != B_OK) {
     838        return ENODEV;
     839    }
     840
     841    ((struct root_device_softc *)dev->root->softc)->is_msix = true;
     842    info->u.h0.interrupt_line = startVector;
     843    return EOK;
    819844}
    820845
    821846
  • src/libs/compat/freebsd_network/device.h

    diff --git a/src/libs/compat/freebsd_network/device.h b/src/libs/compat/freebsd_network/device.h
    index 481d4d4..9a63201 100644
    a b extern "C" {  
    3030
    3131struct root_device_softc {
    3232    struct pci_info pci_info;
     33    bool            is_msi;
     34    bool            is_msix;
    3335};
    3436
    3537enum {