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; } }
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; }