devLib2  2.12
devLibPCI.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2010 Brookhaven Science Associates, as Operator of
3 * Brookhaven National Laboratory.
4 * devLib2 is distributed subject to a Software License Agreement found
5 * in file LICENSE that is included with this distribution.
6 \*************************************************************************/
7 /*
8  * Author: Michael Davidsaver <mdavidsaver@gmail.com>
9  */
10 
11 #include <stdlib.h>
12 #include <string.h>
13 #include <ctype.h>
14 
15 #include <ellLib.h>
16 #include <errlog.h>
17 #include <epicsThread.h>
18 #include <epicsMutex.h>
19 #include <iocsh.h>
20 #include <epicsStdio.h>
21 
22 #define epicsExportSharedSymbols
23 #include "devLibPCIImpl.h"
24 #include "devLibPCI.h"
25 
26 #ifndef CONTAINER
27 # ifdef __GNUC__
28 # define CONTAINER(ptr, structure, member) ({ \
29  const __typeof(((structure*)0)->member) *_ptr = (ptr); \
30  (structure*)((char*)_ptr - offsetof(structure, member)); \
31  })
32 # else
33 # define CONTAINER(ptr, structure, member) \
34  ((structure*)((char*)(ptr) - offsetof(structure, member)))
35 # endif
36 #endif
37 
38 #if defined(vxWorks) && !defined(_WRS_VXWORKS_MAJOR)
39 /* vxWorks 5 has no strdup */
40 #define strdup(x) ({char*s=malloc(strlen(x)+1);s?strcpy(s,x):s;})
41 #endif
42 
43 #ifdef _WIN32
44 /* Windows uses different name for strtok_r */
45 #define strtok_r strtok_s
46 #endif
47 
48 int devPCIDebug = 0;
49 
50 static ELLLIST pciDrivers;
51 
52 static devLibPCI *pdevLibPCI;
53 
54 static epicsMutexId pciDriversLock;
55 static epicsThreadOnceId devPCIReg_once = EPICS_THREAD_ONCE_INIT;
56 
57 static epicsThreadOnceId devPCIInit_once = EPICS_THREAD_ONCE_INIT;
58 static int devPCIInit_result = 42;
59 
60 /******************* Initialization *********************/
61 
62 static
63 void regInit(void* junk)
64 {
65  (void)junk;
66  pciDriversLock = epicsMutexMustCreate();
67 }
68 
69 int
70 devLibPCIRegisterDriver2(devLibPCI* drv, size_t drvsize)
71 {
72  int ret=0;
73  ELLNODE *cur;
74 
75  if (!drv->name) return 1;
76 
77  if(drvsize!=sizeof(*drv)) {
78  fprintf(stderr, "devLibPCIRegisterDriver() fails with inconsistent PCI OS struct sizes.\n"
79  "expect %lu but given %lu\n"
80  "Please do a clean rebuild of devLib2 and any code with custom PCI OS structs\n",
81  (unsigned long)sizeof(*drv),
82  (unsigned long)drvsize);
83  return S_dev_internal;
84  }
85 
86  epicsThreadOnce(&devPCIReg_once, &regInit, NULL);
87 
88  epicsMutexMustLock(pciDriversLock);
89 
90  for(cur=ellFirst(&pciDrivers); cur; cur=ellNext(cur)) {
91  devLibPCI *other=CONTAINER(cur, devLibPCI, node);
92  if (strcmp(drv->name, other->name)==0) {
93  fprintf(stderr, "Failed to register PCI bus driver: name already taken\n");
94  ret=1;
95  break;
96  }
97  }
98  if (!ret)
99  ellAdd(&pciDrivers, &drv->node);
100 
101  epicsMutexUnlock(pciDriversLock);
102 
103  return ret;
104 }
105 
106 int
107 devLibPCIUse(const char* use)
108 {
109  ELLNODE *cur;
110  devLibPCI *drv;
111 
112  if (!use)
113  use="native";
114 
115  epicsThreadOnce(&devPCIReg_once, &regInit, NULL);
116 
117  epicsMutexMustLock(pciDriversLock);
118 
119  if (pdevLibPCI) {
120  epicsMutexUnlock(pciDriversLock);
121  fprintf(stderr, "PCI bus driver already selected. Can't change selection\n");
122  return 1;
123  }
124 
125  for(cur=ellFirst(&pciDrivers); cur; cur=ellNext(cur)) {
126  drv=CONTAINER(cur, devLibPCI, node);
127  if (strcmp(drv->name, use)==0) {
128  pdevLibPCI = drv;
129  epicsMutexUnlock(pciDriversLock);
130  return 0;
131  }
132  }
133  epicsMutexUnlock(pciDriversLock);
134  fprintf(stderr, "PCI bus driver '%s' not found\n",use);
135  return 1;
136 }
137 
138 const char* devLibPCIDriverName()
139 {
140  const char* ret=NULL;
141 
142  epicsThreadOnce(&devPCIReg_once, &regInit, NULL);
143 
144  epicsMutexMustLock(pciDriversLock);
145  if (pdevLibPCI)
146  ret = pdevLibPCI->name;
147  epicsMutexUnlock(pciDriversLock);
148 
149  return ret;
150 }
151 
152 int
153 devLibPCIMatch(const epicsPCIID *match, const epicsPCIID *dev)
154 {
155  if (match->device!=DEVPCI_ANY_DEVICE && match->device!=dev->device) {
156  if(devPCIDebug>1) printf(" mismatch device %x %x\n",
157  (unsigned)match->device, (unsigned)dev->device);
158  return 0;
159  } else if (match->vendor!=DEVPCI_ANY_VENDOR && match->vendor!=dev->vendor) {
160  if(devPCIDebug>1) printf(" mismatch vendor %x %x\n",
161  (unsigned)match->vendor, (unsigned)dev->vendor);
162  return 0;
163  } else if (match->sub_device!=DEVPCI_ANY_SUBDEVICE && match->sub_device!=dev->sub_device) {
164  if(devPCIDebug>1) printf(" mismatch subdevice %x %x\n",
165  (unsigned)match->sub_device, (unsigned)dev->sub_device);
166  return 0;
167  } else if (match->sub_vendor!=DEVPCI_ANY_SUBVENDOR && match->sub_vendor!=dev->sub_vendor) {
168  if(devPCIDebug>1) printf(" mismatch subvendor %x %x\n",
169  (unsigned)match->sub_vendor, (unsigned)dev->sub_vendor);
170  return 0;
171  } else if (match->pci_class!=DEVPCI_ANY_CLASS && match->pci_class!=dev->pci_class) {
172  if(devPCIDebug>1) printf(" mismatch class %x %x\n",
173  (unsigned)match->pci_class, (unsigned)dev->pci_class);
174  return 0;
175  } else if (match->revision!=DEVPCI_ANY_REVISION && match->revision!=dev->revision) {
176  if(devPCIDebug>1) printf(" mismatch revision %x %x\n",
177  match->revision, dev->revision);
178  return 0;
179  } else {
180  if(devPCIDebug>1)
181  printf(" Match\n");
182  return 1;
183  }
184 }
185 
186 static
187 void devInit(void* junk)
188 {
189  (void)junk;
190  epicsThreadOnce(&devPCIReg_once, &regInit, NULL);
191  epicsMutexMustLock(pciDriversLock);
192  if(!pdevLibPCI && devLibPCIUse(NULL)) {
193  epicsMutexUnlock(pciDriversLock);
194  devPCIInit_result = S_dev_internal;
195  return;
196  }
197  epicsMutexUnlock(pciDriversLock);
198 
199  if(!!pdevLibPCI->pDevInit)
200  devPCIInit_result = (*pdevLibPCI->pDevInit)();
201  else
202  devPCIInit_result = 0;
203 }
204 
205 #define PCIINIT \
206  do { \
207  epicsThreadOnce(&devPCIInit_once, &devInit, NULL); \
208  if (devPCIInit_result) return devPCIInit_result; \
209  } while(0)
210 
211 
212 /**************** API functions *****************/
213 
215  const epicsPCIID *idlist,
216  devPCISearchFn searchfn,
217  void *arg,
218  unsigned int opt /* always 0 */
219  )
220 {
221  if(!idlist || !searchfn)
222  return S_dev_badArgument;
223 
224  PCIINIT;
225 
226  return (*pdevLibPCI->pDevPCIFind)(idlist,searchfn,arg,opt);
227 }
228 
229 
230 struct bdfmatch
231 {
232  unsigned int matchaddr:1;
233  unsigned int matchslot:1;
234 
235  unsigned int domain,b,d,f;
236  char slot[11];
237  unsigned int sofar, stopat;
238 
240 };
241 
242 static
243 int devmatch(void* ptr, const epicsPCIDevice* cur)
244 {
245  struct bdfmatch *mt=ptr;
246 
247  unsigned match = 1;
248 
249  if(mt->matchaddr)
250  match &= cur->domain==mt->domain &&
251  cur->bus==mt->b &&
252  cur->device==mt->d &&
253  cur->function==mt->f;
254 
255  if(mt->matchslot)
256  match &= cur->slot==DEVPCI_NO_SLOT ? 0 : strcmp(cur->slot, mt->slot)==0;
257 
258  if(match && mt->sofar++==mt->stopat)
259  {
260  mt->found=cur;
261  return 1;
262  }
263 
264  return 0;
265 }
266 
268  const epicsPCIID *idlist,
269  const char *spec,
270  const epicsPCIDevice **found,
271  unsigned int opt
272  )
273 {
274  int err = 0;
275  struct bdfmatch find;
276  memset(&find, 0, sizeof(find));
277 
278  if(!found || !spec)
279  return S_dev_badArgument;
280 
281  /* When originally introduced in 2.8, devPCIFindSpec() parsed as decimal,
282  * which is confusing as BDF are usually shown in hex.
283  * Changed in 2.9 to parse as hex.
284  * TODO: remove this notice after 2.9
285  */
286  if(devPCIDebug>=0) {
287  static int shown=0;
288  if(!shown) {
289  fprintf(stderr, "Notice: devPCIFindSpec() expect B:D.F in hex\n");
290  shown = 1;
291  }
292  }
293 
294  /* parse the spec. string */
295  {
296  char *save, *alloc, *tok;
297 
298  alloc = strdup(spec);
299  if(!alloc) return S_dev_noMemory;
300 
301  for(tok = strtok_r(alloc, " ", &save);
302  tok;
303  tok=strtok_r(NULL, " ", &save))
304  {
305  unsigned dom, bus, dev, func=0;
306 
307  if(sscanf(tok, "%x:%x:%x.%x", &dom, &bus, &dev, &func)>=3) {
308  find.matchaddr = 1;
309  find.domain = dom;
310  find.b = bus;
311  find.d = dev;
312  find.f = func;
313 
314  } else if(sscanf(tok, "%x:%x.%x", &bus, &dev, &func)>=2) {
315  find.matchaddr = 1;
316  find.domain = 0;
317  find.b = bus;
318  find.d = dev;
319  find.f = func;
320 
321  } else if(sscanf(tok, "slot=%10s", find.slot)==1) {
322  if(strlen(find.slot)==10)
323  fprintf(stderr, "Slot label '%s' truncated?\n", find.slot);
324  find.matchslot = 1;
325 
326  } else if(sscanf(tok, "instance=%u", &dom)==1) {
327  find.stopat = dom==0 ? 0 : dom-1;
328 
329  } else if(sscanf(tok, "inst=%u", &dom)==1) {
330  find.stopat = dom==0 ? 0 : dom-1;
331 
332  } else if(strchr(tok, '=')!=NULL) {
333  fprintf(stderr, "Ignoring unknown spec '%s'\n", tok);
334 
335  } else {
336  fprintf(stderr, "Error: invalid spec '%s'\n", tok);
337  err = S_dev_badArgument;
338  }
339  }
340 
341  free(alloc);
342  }
343 
344  if(err)
345  return err;
346 
347  if(devPCIDebug>4) {
348  if(find.matchaddr)
349  fprintf(stderr, " Match BDF %x:%x:%x.%x\n",
350  find.domain, find.b, find.d, find.f);
351  if(find.matchslot)
352  fprintf(stderr, " Match slot %s\n", find.slot);
353  fprintf(stderr, " Instance %u\n", find.stopat);
354  }
355 
356  /* PCIINIT is called by devPCIFindCB() */
357 
358  err=devPCIFindCB(idlist,&devmatch,&find, opt);
359  if(err!=0){
360  /* Search failed? */
361  return err;
362  }
363 
364  if(!find.found){
365  /* Not found */
366  return S_dev_noDevice;
367  }
368 
369  *found=find.found;
370  return 0;
371 }
372 
373 /*
374  * The most common PCI search using only id fields and BDF.
375  */
377  const epicsPCIID *idlist,
378  unsigned int domain,
379  unsigned int b,
380  unsigned int d,
381  unsigned int f,
382  const epicsPCIDevice **found,
383  unsigned int opt
384  )
385 {
386  int err;
387  struct bdfmatch find;
388 
389  if(!found)
390  return S_dev_badArgument;
391 
392  memset(&find, 0, sizeof(find));
393  find.matchaddr = 1;
394  find.domain=domain;
395  find.b=b;
396  find.d=d;
397  find.f=f;
398  find.found=NULL;
399 
400  /* PCIINIT is called by devPCIFindCB() */
401 
402  err=devPCIFindCB(idlist,&devmatch,&find, opt);
403  if(err!=0){
404  /* Search failed? */
405  return err;
406  }
407 
408  if(!find.found){
409  /* Not found */
410  return S_dev_noDevice;
411  }
412 
413  *found=find.found;
414  return 0;
415 }
416 
417 /* for backward compatilility: b=domain*0x100+bus */
419  const epicsPCIID *idlist,
420  unsigned int b,
421  unsigned int d,
422  unsigned int f,
423  const epicsPCIDevice **found,
424  unsigned int opt
425  )
426 {
427  return devPCIFindDBDF(idlist, b>>8, b&0xff, d, f, found, opt);
428 }
429 
430 int
432  const epicsPCIDevice *curdev,
433  unsigned int bar,
434  volatile void **ppLocalAddr,
435  unsigned int opt
436  )
437 {
438  PCIINIT;
439 
440  if(bar>=PCIBARCOUNT)
441  return S_dev_badArgument;
442 
443  return (*pdevLibPCI->pDevPCIToLocalAddr)(curdev,bar,ppLocalAddr,opt);
444 }
445 
446 
447 
448 int
450  const epicsPCIDevice *curdev,
451  unsigned int bar,
452  epicsUInt32 *len
453  )
454 {
455  PCIINIT;
456 
457  if(bar>=PCIBARCOUNT)
458  return S_dev_badArgument;
459 
460  return (*pdevLibPCI->pDevPCIBarLen)(curdev,bar,len);
461 }
462 
464  const epicsPCIDevice *curdev,
465  void (*pFunction)(void *),
466  void *parameter,
467  unsigned int opt
468  )
469 {
470  PCIINIT;
471 
472  return (*pdevLibPCI->pDevPCIConnectInterrupt)
473  (curdev,pFunction,parameter,opt);
474 }
475 
477  const epicsPCIDevice *curdev,
478  void (*pFunction)(void *),
479  void *parameter
480  )
481 {
482  PCIINIT;
483 
484  return (*pdevLibPCI->pDevPCIDisconnectInterrupt)
485  (curdev,pFunction,parameter);
486 }
487 
488 typedef struct {
489  int lvl;
490  int matched;
491 } searchinfo;
492 
493 static
494 int
495 searchandprint(void* praw,const epicsPCIDevice* dev)
496 {
497  searchinfo *pinfo=praw;
498  pinfo->matched++;
499  devPCIShowDevice(pinfo->lvl,dev);
500  return 0;
501 }
502 
503 void
504 devPCIShow(int lvl, int vendor, int device, int exact)
505 {
506  epicsPCIID ids[] = {
507  DEVPCI_DEVICE_VENDOR(device,vendor),
508  DEVPCI_END
509  };
510  searchinfo info;
511  info.lvl=lvl;
512  info.matched=0;
513 
514  if (vendor==0 && !exact) ids[0].vendor=DEVPCI_ANY_VENDOR;
515  if (device==0 && !exact) ids[0].device=DEVPCI_ANY_DEVICE;
516 
517  devPCIFindCB(ids,&searchandprint, &info, 0);
518  printf("Matched %d devices\n", info.matched);
519 }
520 
521 void
522 devPCIShowMatch(int lvl, const char *spec, int vendor, int device)
523 {
524  epicsPCIID ids[] = {
525  DEVPCI_DEVICE_VENDOR(device,vendor),
526  DEVPCI_END
527  };
528  const epicsPCIDevice *found = NULL;
529 
530  if (vendor==0) ids[0].vendor=DEVPCI_ANY_VENDOR;
531  if (device==0) ids[0].device=DEVPCI_ANY_DEVICE;
532 
533  if(!devPCIFindSpec(ids, spec, &found, 0)) {
534  devPCIShowDevice(lvl, found);
535  } else {
536  printf("No match\n");
537  }
538 }
539 
540 void
541 devPCIShowDevice(int lvl, const epicsPCIDevice *dev)
542 {
543  unsigned int i;
544 
545  printf("PCI %04x:%02x:%02x.%x IRQ %u\n"
546  " vendor:device %04x:%04x rev %02x\n",
547  dev->domain, dev->bus, dev->device, dev->function, dev->irq,
548  dev->id.vendor, dev->id.device, dev->id.revision);
549  if(lvl<1)
550  return;
551  printf(" subved:subdev %04x:%04x\n"
552  " class %06x %s\n",
553  dev->id.sub_vendor, dev->id.sub_device,
554  dev->id.pci_class,
556  if(dev->slot!=DEVPCI_NO_SLOT)
557  printf(" slot: %s\n", dev->slot);
558  if (dev->driver) printf(" driver %s\n",
559  dev->driver);
560  if(lvl<2)
561  return;
562  for(i=0; i<PCIBARCOUNT; i++)
563  {
564  epicsUInt32 len;
565 
566  if ((*pdevLibPCI->pDevPCIBarLen)(dev, i, &len) == 0 && len > 0)
567  {
568  char* u = "";
569  if (len >= 1024) { len >>= 10; u = "k"; }
570  if (len >= 1024) { len >>= 10; u = "M"; }
571  if (len >= 1024) { len >>= 10; u = "G"; }
572 
573  printf(" BAR %u %s-bit %s%s %3u %sB\n",i,
574  dev->bar[i].addr64?"64":"32",
575  dev->bar[i].ioport?"IO Port":"MMIO ",
576  dev->bar[i].below1M?" Below 1M":"",
577  len, u);
578  }
579  /* 64 bit bars use 2 entries */
580  if (dev->bar[i].addr64) i++;
581  }
582 }
583 
584 static int
585 checkCfgAccess(const epicsPCIDevice *dev, unsigned offset, void *arg, devPCIAccessMode mode)
586 {
587  int rval;
588 
589  if ( (offset & (CFG_ACC_WIDTH(mode) - 1)) )
590  return S_dev_badArgument; /* misaligned */
591  if ( ! pdevLibPCI->pDevPCIConfigAccess )
592  return S_dev_badFunction; /* not implemented */
593 
594  rval = (*pdevLibPCI->pDevPCIConfigAccess)(dev, offset, arg, mode);
595 
596  if ( rval )
597  return rval;
598 
599  return 0;
600 }
601 
602 int
603 devPCIConfigRead8(const epicsPCIDevice *dev, unsigned offset, epicsUInt8 *pResult)
604 {
605  return checkCfgAccess(dev, offset, pResult, RD_08);
606 }
607 
608 int
609 devPCIConfigRead16(const epicsPCIDevice *dev, unsigned offset, epicsUInt16 *pResult)
610 {
611  return checkCfgAccess(dev, offset, pResult, RD_16);
612 }
613 
614 int
615 devPCIConfigRead32(const epicsPCIDevice *dev, unsigned offset, epicsUInt32 *pResult)
616 {
617  return checkCfgAccess(dev, offset, pResult, RD_32);
618 }
619 
620 int
621 devPCIConfigWrite8(const epicsPCIDevice *dev, unsigned offset, epicsUInt8 value)
622 {
623  return checkCfgAccess(dev, offset, &value, WR_08);
624 }
625 
626 int
627 devPCIConfigWrite16(const epicsPCIDevice *dev, unsigned offset, epicsUInt16 value)
628 {
629  return checkCfgAccess(dev, offset, &value, WR_16);
630 }
631 
632 int
633 devPCIConfigWrite32(const epicsPCIDevice *dev, unsigned offset, epicsUInt32 value)
634 {
635  return checkCfgAccess(dev, offset, &value, WR_32);
636 }
637 
638 
639 int
641 {
642  if ( ! pdevLibPCI->pDevPCIConfigAccess )
643  return S_dev_badFunction; /* not implemented */
644 
645  return pdevLibPCI->pDevPCISwitchInterrupt(dev, 0);
646 }
647 
648 int
650 {
651  if ( ! pdevLibPCI->pDevPCIConfigAccess )
652  return S_dev_badFunction; /* not implemented */
653 
654  return pdevLibPCI->pDevPCISwitchInterrupt(dev, 1);
655 }
656 
657 
658 static const iocshArg devPCIShowArg0 = { "verbosity level",iocshArgInt};
659 static const iocshArg devPCIShowArg1 = { "PCI Vendor ID (0=any)",iocshArgInt};
660 static const iocshArg devPCIShowArg2 = { "PCI Device ID (0=any)",iocshArgInt};
661 static const iocshArg devPCIShowArg3 = { "exact (1=treat 0 as 0)",iocshArgInt};
662 static const iocshArg * const devPCIShowArgs[4] =
663 {&devPCIShowArg0,&devPCIShowArg1,&devPCIShowArg2,&devPCIShowArg3};
664 static const iocshFuncDef devPCIShowFuncDef =
665 {"devPCIShow",4,devPCIShowArgs};
666 static void devPCIShowCallFunc(const iocshArgBuf *args)
667 {
668  devPCIShow(args[0].ival,args[1].ival,args[2].ival,args[3].ival);
669 }
670 
671 static const iocshArg devLibPCIUseArg0 = { "verbosity level",iocshArgString};
672 static const iocshArg * const devLibPCIUseArgs[1] =
673 {&devLibPCIUseArg0};
674 static const iocshFuncDef devLibPCIUseFuncDef =
675 {"devLibPCIUse",1,devLibPCIUseArgs};
676 static void devLibPCIUseCallFunc(const iocshArgBuf *args)
677 {
678  devLibPCIUse(args[0].sval);
679 }
680 
681 #include <epicsExport.h>
682 
683 static
684 void devLibPCIIOCSH()
685 {
686  iocshRegister(&devPCIShowFuncDef,devPCIShowCallFunc);
687  iocshRegister(&devLibPCIUseFuncDef,devLibPCIUseCallFunc);
688 }
689 
690 epicsExportRegistrar(devLibPCIIOCSH);
691 
#define DEVPCI_END
The last item in a list of PCI IDS.
Definition: devLibPCI.h:72
const char * driver
Definition: devLibPCI.h:122
#define DEVPCI_ANY_REVISION
Definition: devLibPCI.h:67
int(* devPCISearchFn)(void *ptr, const epicsPCIDevice *dev)
PCI search callback prototype.
Definition: devLibPCI.h:136
#define DEVPCI_ANY_SUBVENDOR
Definition: devLibPCI.h:65
epicsUInt32 sub_device
Definition: devLibPCI.h:57
unsigned int stopat
Definition: devLibPCI.c:237
int devPCIEnableInterrupt(const epicsPCIDevice *dev)
Enable interrupts at the device.
Definition: devLibPCI.c:640
const char * devLibPCIDriverName()
Definition: devLibPCI.c:138
int devPCIConnectInterrupt(const epicsPCIDevice *curdev, void(*pFunction)(void *), void *parameter, unsigned int opt)
Request interrupts for device.
Definition: devLibPCI.c:463
unsigned int ioport
Definition: devLibPCI.h:98
int(* pDevPCISwitchInterrupt)(const epicsPCIDevice *id, int level)
Definition: devLibPCIImpl.h:64
int devPCIConfigWrite32(const epicsPCIDevice *dev, unsigned offset, epicsUInt32 value)
Write (32-bit) dword from configuration space.
Definition: devLibPCI.c:633
#define DEVPCI_ANY_CLASS
Definition: devLibPCI.h:66
int devPCIDisableInterrupt(const epicsPCIDevice *dev)
Enable interrupts at the device.
Definition: devLibPCI.c:649
unsigned int b
Definition: devLibPCI.c:235
int devLibPCIMatch(const epicsPCIID *match, const epicsPCIID *dev)
Definition: devLibPCI.c:153
#define DEVPCI_DEVICE_VENDOR(dev, vend)
Definition: devLibPCI.h:79
int devPCIConfigWrite16(const epicsPCIDevice *dev, unsigned offset, epicsUInt16 value)
Write (16-bit) word from configuration space.
Definition: devLibPCI.c:627
#define PCIINIT
Definition: devLibPCI.c:205
unsigned int below1M
Definition: devLibPCI.h:100
devPCIAccessMode
Definition: devLibPCIImpl.h:27
epicsUInt32 sub_vendor
Definition: devLibPCI.h:57
unsigned int bus
Definition: devLibPCI.h:114
epicsUInt8 irq
Definition: devLibPCI.h:120
int devPCIConfigRead8(const epicsPCIDevice *dev, unsigned offset, epicsUInt8 *pResult)
Read byte from configuration space.
Definition: devLibPCI.c:603
#define PCIBARCOUNT
The maximum number of base address registers (BARs).
Definition: devLibPCI.h:126
int devPCIDebug
Definition: devLibPCI.c:48
#define CONTAINER(ptr, structure, member)
Definition: devLibPCI.c:33
const epicsPCIDevice * found
Definition: devLibPCI.c:239
int matched
Definition: devLibPCI.c:490
int devPCIToLocalAddr(const epicsPCIDevice *curdev, unsigned int bar, volatile void **ppLocalAddr, unsigned int opt)
Get pointer to PCI BAR.
Definition: devLibPCI.c:431
const char * name
Definition: devLibPCIImpl.h:40
void devPCIShowDevice(int lvl, const epicsPCIDevice *dev)
Definition: devLibPCI.c:541
#define DEVPCI_ANY_VENDOR
Definition: devLibPCI.h:63
int devLibPCIRegisterDriver2(devLibPCI *drv, size_t drvsize)
Definition: devLibPCI.c:70
#define DEVPCI_NO_SLOT
Definition: devLibPCI.h:95
epicsUInt32 device
Definition: devLibPCI.h:56
#define CFG_ACC_WIDTH(mode)
Definition: devLibPCIImpl.h:36
int(* pDevPCIConfigAccess)(const epicsPCIDevice *id, unsigned offset, void *pArg, devPCIAccessMode mode)
Definition: devLibPCIImpl.h:61
void devPCIShowMatch(int lvl, const char *spec, int vendor, int device)
Definition: devLibPCI.c:522
Device token.
Definition: devLibPCI.h:112
int devPCIConfigRead16(const epicsPCIDevice *dev, unsigned offset, epicsUInt16 *pResult)
Read (16-bit) word from configuration space.
Definition: devLibPCI.c:609
unsigned int domain
Definition: devLibPCI.c:235
unsigned int domain
Definition: devLibPCI.h:121
unsigned int device
Definition: devLibPCI.h:115
struct PCIBar bar[6]
Definition: devLibPCI.h:119
int(* pDevPCIDisconnectInterrupt)(const epicsPCIDevice *id, void(*pFunction)(void *), void *parameter)
Definition: devLibPCIImpl.h:57
int devPCIFindDBDF(const epicsPCIID *idlist, unsigned int domain, unsigned int b, unsigned int d, unsigned int f, const epicsPCIDevice **found, unsigned int opt)
PCI bus probe.
Definition: devLibPCI.c:376
unsigned int sofar
Definition: devLibPCI.c:237
int(* pDevInit)(void)
Definition: devLibPCIImpl.h:42
int(* pDevPCIToLocalAddr)(const epicsPCIDevice *dev, unsigned int bar, volatile void **a, unsigned int o)
Definition: devLibPCIImpl.h:48
int devPCIFindSpec(const epicsPCIID *idlist, const char *spec, const epicsPCIDevice **found, unsigned int opt)
PCI bus search by specification string.
Definition: devLibPCI.c:267
int devPCIDisconnectInterrupt(const epicsPCIDevice *curdev, void(*pFunction)(void *), void *parameter)
Stop receiving interrupts.
Definition: devLibPCI.c:476
unsigned int matchslot
Definition: devLibPCI.c:233
PCI device identifier.
Definition: devLibPCI.h:55
int devPCIConfigWrite8(const epicsPCIDevice *dev, unsigned offset, epicsUInt8 value)
Write byte to configuration space.
Definition: devLibPCI.c:621
unsigned int addr64
Definition: devLibPCI.h:99
int(* pDevPCIFind)(const epicsPCIID *ids, devPCISearchFn searchfn, void *arg, unsigned int o)
Definition: devLibPCIImpl.h:46
epicsUInt16 revision
Definition: devLibPCI.h:59
#define DEVPCI_ANY_SUBDEVICE
Definition: devLibPCI.h:64
unsigned int d
Definition: devLibPCI.c:235
epicsExportAddress(int, devPCIDebug)
const char * slot
Definition: devLibPCI.h:118
int devPCIFindBDF(const epicsPCIID *idlist, unsigned int b, unsigned int d, unsigned int f, const epicsPCIDevice **found, unsigned int opt)
Definition: devLibPCI.c:418
int devLibPCIUse(const char *use)
Select driver implementation. Pick driver implementation by name, or NULL to use default. If no selection is made then the default will be used if available.
Definition: devLibPCI.c:107
epicsShareFunc const char * devPCIDeviceClassToString(int classId)
Translate class id to string.
#define DEVPCI_ANY_DEVICE
Definition: devLibPCI.h:62
int(* pDevPCIConnectInterrupt)(const epicsPCIDevice *id, void(*pFunction)(void *), void *parameter, unsigned int opt)
Definition: devLibPCIImpl.h:52
char slot[11]
Definition: devLibPCI.c:236
void devPCIShow(int lvl, int vendor, int device, int exact)
Definition: devLibPCI.c:504
unsigned int matchaddr
Definition: devLibPCI.c:232
int devPCIBarLen(const epicsPCIDevice *curdev, unsigned int bar, epicsUInt32 *len)
Find the size of a BAR.
Definition: devLibPCI.c:449
epicsPCIID id
Exact ID of device.
Definition: devLibPCI.h:113
epicsUInt32 pci_class
Definition: devLibPCI.h:58
int devPCIConfigRead32(const epicsPCIDevice *dev, unsigned offset, epicsUInt32 *pResult)
Read (32-bit) dword from configuration space.
Definition: devLibPCI.c:615
ELLNODE node
Definition: devLibPCIImpl.h:65
epicsUInt32 vendor
Definition: devLibPCI.h:56
unsigned int function
Definition: devLibPCI.h:116
int devPCIFindCB(const epicsPCIID *idlist, devPCISearchFn searchfn, void *arg, unsigned int opt)
PCI bus search w/ callback.
Definition: devLibPCI.c:214
unsigned int f
Definition: devLibPCI.c:235
epicsExportRegistrar(devLibPCIIOCSH)
int(* pDevPCIBarLen)(const epicsPCIDevice *dev, unsigned int bar, epicsUInt32 *len)
Definition: devLibPCIImpl.h:50