Пример #1
0
int
sharedDevPCIConfigAccess(const epicsPCIDevice *dev, unsigned offset, void *pArg, devPCIAccessMode mode)
{
    int st = 1;

    if ( CFG_ACC_WRITE(mode) ) {
        switch ( CFG_ACC_WIDTH(mode) ) {
        default:
        case 1:
            st = pci_write_config_byte( dev->bus, dev->device, dev->function, (unsigned char)offset, *(uint8_t*)pArg );
            break;

        case 2:
            st = pci_write_config_word( dev->bus, dev->device, dev->function, (unsigned char)offset, *(uint16_t*)pArg );
            break;
        case 4:
            st = pci_write_config_dword( dev->bus, dev->device, dev->function, (unsigned char)offset, *(uint32_t*)pArg );
            break;
        }
    } else {
        switch ( CFG_ACC_WIDTH(mode) ) {
        default:
        case 1:
            st = pci_read_config_byte( dev->bus, dev->device, dev->function, (unsigned char)offset, pArg );
            break;

        case 2:
            st = pci_read_config_word( dev->bus, dev->device, dev->function, (unsigned char)offset, pArg );
            break;
        case 4:
            st = pci_read_config_dword( dev->bus, dev->device, dev->function, (unsigned char)offset, pArg );
            break;
        }
    }

    if (st) {
        errlogPrintf("devLibPCIOSD: Unable to %s %u bytes %s configuration space: PCIBIOS error code 0x%02x\n",
                     CFG_ACC_WRITE(mode) ? "write" : "read",
                     CFG_ACC_WIDTH(mode),
                     CFG_ACC_WRITE(mode) ? "to" : "from",
                     st);

        return S_dev_internal;
    } else {
        return 0;
    }
}
Пример #2
0
static int
linuxDevPCIConfigAccess(const epicsPCIDevice *dev, unsigned offset, void *pArg, devPCIAccessMode mode)
{
    int           rval    = S_dev_internal;
    char         *scratch = 0;
    osdPCIDevice *osd     = CONTAINER((epicsPCIDevice*)dev,osdPCIDevice,dev);
    ssize_t       st;
    int           cmode;

    epicsMutexMustLock(osd->devLock);

    if ( CMODE_NONE == osd->cmode ) {
        /* have already tried to open */
        rval = S_dev_badRequest;
        goto bail;
    }

    if ( -1 == osd->cfd ) {
        if ( ! (scratch = allocPrintf(BUSBASE"config",
                    osd->dev.domain, osd->dev.bus, osd->dev.device, osd->dev.function)) ) {
            rval = S_dev_noMemory;
            goto bail;
        }
        if ( (osd->cfd = open(scratch, O_RDWR, 0)) < 0 ) {
            fprintf(stderr, "devLibPCIOSD: Unable to open configuration space for writing: %s\n", strerror(errno));
            /* try readonly */
            if ( (osd->cfd = open(scratch, O_RDONLY, 0)) < 0 ) {
                fprintf(stderr, "devLibPCIOSD: Unable to open configuration space for read-only: %s\n", strerror(errno));
                rval = S_dev_badRequest;
                osd->cmode = CMODE_NONE;
                goto bail;
            }
            osd->cmode = CMODE_RONL;
        } else {
            osd->cmode = CMODE_RDWR;
        }
    }

    cmode = (CFG_ACC_WRITE(mode) ? CMODE_WRTE : CMODE_READ);

    if ( ! (osd->cmode & cmode) ) {
        rval = S_dev_badRequest;
        goto bail;
    }

    if ( CFG_ACC_WRITE(mode) ) {
        st = pwrite( osd->cfd, pArg, CFG_ACC_WIDTH(mode), offset );
    } else {
        st = pread( osd->cfd, pArg, CFG_ACC_WIDTH(mode), offset );
    }

    if ( CFG_ACC_WIDTH(mode) != st ) {
        if ( st < 0 )
            fprintf(stderr, "devLibPCIOSD: Unable to %s %u bytes %s configuration space: %s\n",
                         CFG_ACC_WRITE(mode) ? "write" : "read",
                         CFG_ACC_WIDTH(mode),
                         CFG_ACC_WRITE(mode) ? "to" : "from",
                         strerror(errno));

        rval = S_dev_internal;
        goto bail;
    }

    rval = 0;

bail:
    free(scratch);

    epicsMutexUnlock(osd->devLock);

    return rval;
}