/*************************************************************************\ * Copyright (c) 2010 Brookhaven Science Associates, as Operator of * Brookhaven National Laboratory. * devLib2 is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* * Author: Michael Davidsaver */ #include #include #include #include #include #include #include #include #include static volatile void *diagbase=0; static volatile epicsUInt32 diaglen=0; struct bdf { int b,d,f; const epicsPCIDevice *dev; }; static int matchbdf(void* raw,const epicsPCIDevice* dev) { struct bdf *loc=raw; if(dev->bus!=loc->b || dev->device!=loc->d || dev->function!=loc->f) return 0; loc->dev=dev; return 1; } void pcidiagset(int b, int d, int f, int bar, int vendor, int device, int exact) { epicsUInt32 len=0; struct bdf loc; epicsPCIID ids[] = { DEVPCI_DEVICE_VENDOR(device,vendor), DEVPCI_END }; printf("Looking for %u:%u.%u\n", b, d, f); if(vendor==0 && !exact) ids[0].vendor=DEVPCI_ANY_VENDOR; if(device==0 && !exact) ids[0].device=DEVPCI_ANY_DEVICE; loc.b=b; loc.d=d; loc.f=f; loc.dev=0; if(devPCIFindCB(ids, &matchbdf, (void*)&loc, 0)) { printf("Error searching\n"); return; } if(!loc.dev) { printf("No such device\n"); return; } printf("Mapping %u:%u.%u\n", loc.dev->bus, loc.dev->device, loc.dev->function); #if defined(linux) if(devPCIBarLen(loc.dev, bar, &len)) { printf("Failed to get BAR length\n"); len=0; } #endif if(devPCIToLocalAddr(loc.dev, bar, &diagbase, 0)) { printf("Failed to map BAR\n"); return; } diaglen=len; #if defined(linux) printf("BAR %u from 0x%08lx for %u bytes\n",bar, (unsigned long)diagbase, diaglen); #else printf("BAR %u from 0x%08lx\n",bar, (unsigned long)diagbase); #endif } void pciread(int dmod, int offset, int count) { epicsUInt32 tval; volatile char* dptr; short dbytes; int i; if(!diagbase) { printf("Run pcidiagset first\n"); return; } switch(dmod){ case 8: case 16: case 32: break; default: epicsPrintf("Invalid data width %d\n",dmod); return; } dbytes=dmod/8; if(dmod%8) dbytes++; if(dbytes <=0 || dbytes>4){ epicsPrintf("Invalid data width\n"); return; } if(count diaglen) { printf("Out of range\n"); return; } count/=dbytes; for(i=0, dptr=diagbase+offset; i