14 #include <epicsMutex.h> 15 #include <epicsInterrupt.h> 21 #define epicsExportSharedSymbols 24 #ifndef PCI_MEM_OFFSET 25 # define PCI_MEM_OFFSET 0 29 # define PCI_IO_OFFSET 0 33 static ELLLIST devices;
38 unsigned int b, d, f, bar;
56 if (d == 31 && f == 7)
60 pci_read_config_dword(b,d,f,PCI_VENDOR_ID, &val32);
61 if (val32 == 0xffffffff)
65 errlogPrintf(
"sharedDevPCIInit found %d.%d.%d: %08x\n",b,d,f, (
unsigned)val32);
69 return S_dev_noMemory;
78 pci_read_config_dword(b,d,f,PCI_SUBSYSTEM_VENDOR_ID, &val32);
82 pci_read_config_dword(b,d,f,PCI_CLASS_REVISION, &val32);
87 errlogPrintf(
" as pri %04x:%04x sub %04x:%04x cls %06x\n",
92 pci_read_config_byte(b,d,f,PCI_HEADER_TYPE, &header);
94 if (bar>=2 && (header & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE)
97 errlogPrintf(
" bridge device\n");
100 pci_read_config_dword(b,d,f,PCI_BASE_ADDRESS(bar), &val32);
101 next->
dev.
bar[bar].
ioport = (val32 & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO;
107 next->
dev.
bar[bar].
below1M = !!(val32&PCI_BASE_ADDRESS_MEM_TYPE_1M);
108 next->
dev.
bar[bar].
addr64 = !!(val32&PCI_BASE_ADDRESS_MEM_TYPE_64);
114 pci_read_config_dword(b,d,f,PCI_BASE_ADDRESS(bar), &val32);
115 next->
base[bar] = val32;
120 pci_read_config_dword(b,d,f,PCI_ROM_ADDRESS, &val32);
121 next->
erom = val32 & PCI_ROM_ADDRESS_MASK;
123 pci_read_config_byte(b,d,f,PCI_INTERRUPT_LINE, &val8);
126 ellInsert(&devices,ellLast(&devices),&next->
node);
128 if (f == 0 && !(header & PCI_HEADER_MULTI_FUNC))
131 errlogPrintf(
" single function device\n");
160 errlogPrintf(
"sharedDevPCIFindCB\n");
162 if(!searchfn || !idlist)
163 return S_dev_badArgument;
165 cur=ellFirst(&devices);
166 for(; cur; cur=ellNext(cur)){
169 for(search=idlist; search && !!search->
device; search++){
176 err=searchfn(arg,&curdev->
dev);
197 volatile void **ppLocalAddr,
209 return S_dev_addrMapFail;
213 #if __SIZEOF_POINTER__ > 4 214 *ppLocalAddr=(
volatile void*)(osd->
base[bar] | (
long long)osd->
base[bar+1] << 32);
217 if (osd->
base[bar+1])
219 errlogPrintf(
"sharedDevPCIToLocalAddr: Unable map a 64 bit BAR on a 32 bit system");
220 return S_dev_addrMapFail;
224 *ppLocalAddr=(
volatile void*)osd->
base[bar];
238 PCIUINT32 start, max, mask;
242 return S_dev_badSignalNumber;
248 iflag=epicsInterruptLock();
252 epicsInterruptUnlock(iflag);
259 mask=PCI_BASE_ADDRESS_IO_MASK;
261 mask=PCI_BASE_ADDRESS_MEM_MASK;
272 pci_read_config_dword(b,d,f,PCI_BASE_ADDRESS(bar), &start);
275 if((start&mask)==0) {
276 epicsInterruptUnlock(iflag);
277 return S_dev_badRequest;
280 pci_write_config_dword(b,d,f,PCI_BASE_ADDRESS(bar), mask);
281 pci_read_config_dword(b,d,f,PCI_BASE_ADDRESS(bar), &max);
282 pci_write_config_dword(b,d,f,PCI_BASE_ADDRESS(bar), start);
288 osd->
len[bar] = max & ~(max-1);
291 epicsInterruptUnlock(iflag);
304 st = pci_write_config_byte( dev->
bus, dev->
device, dev->
function, (
unsigned char)offset, *(uint8_t*)pArg );
308 st = pci_write_config_word( dev->
bus, dev->
device, dev->
function, (
unsigned char)offset, *(uint16_t*)pArg );
311 st = pci_write_config_dword( dev->
bus, dev->
device, dev->
function, (
unsigned char)offset, *(uint32_t*)pArg );
318 st = pci_read_config_byte( dev->
bus, dev->
device, dev->
function, (
unsigned char)offset, pArg );
322 st = pci_read_config_word( dev->
bus, dev->
device, dev->
function, (
unsigned char)offset, pArg );
325 st = pci_read_config_dword( dev->
bus, dev->
device, dev->
function, (
unsigned char)offset, pArg );
331 errlogPrintf(
"devLibPCIOSD: Unable to %s %u bytes %s configuration space: PCIBIOS error code 0x%02x\n",
337 return S_dev_internal;
int(* devPCISearchFn)(void *ptr, const epicsPCIDevice *dev)
PCI search callback prototype.
int sharedDevPCIFindCB(const epicsPCIID *idlist, devPCISearchFn searchfn, void *arg, unsigned int opt)
epicsUInt32 len[PCIBARCOUNT]
int sharedDevPCIBarLen(const epicsPCIDevice *dev, unsigned int bar, epicsUInt32 *len)
int devLibPCIMatch(const epicsPCIID *match, const epicsPCIID *dev)
#define PCIBARCOUNT
The maximum number of base address registers (BARs).
#define CONTAINER(ptr, structure, member)
#define CFG_ACC_WRITE(mode)
int sharedDevPCIToLocalAddr(const epicsPCIDevice *dev, unsigned int bar, volatile void **ppLocalAddr, unsigned int opt)
#define CFG_ACC_WIDTH(mode)
epicsUInt32 base[PCIBARCOUNT]
int sharedDevPCIConfigAccess(const epicsPCIDevice *dev, unsigned offset, void *pArg, devPCIAccessMode mode)
int sharedDevPCIInit(void)
epicsPCIID id
Exact ID of device.
INLINE osdPCIDevice * pcidev2osd(const epicsPCIDevice *devptr)