25 static const char sccsID[] = 
"@(#) $Id$";
    31 #define epicsExportSharedSymbols    33 #include "epicsMutex.h"    37 #define NO_DEVLIB_COMPAT    40 static ELLLIST addrAlloc[
atLast];
    41 static ELLLIST addrFree[
atLast];
    43 static size_t addrLast[
atLast] = {
    51 static unsigned addrHexDig[
atLast] = {
    59 static long  addrFail[
atLast] = {
    67 static epicsMutexId addrListLock;
    68 static char devLibInitFlag;
    96 static long devLibInit(
void);
    98 static long addrVerify(
    99             epicsAddressType addrType,
   103 static long blockFind (
   104             epicsAddressType addrType,
   113 static void report_conflict(
   114             epicsAddressType addrType,
   117             const char *pOwnerName);
   119 static void report_conflict_device(
   120             epicsAddressType addrType,
   123 static void devInsertAddress(
   127 static long devListAddressMap(
   128             ELLLIST             *pRangeList);
   130 static long devCombineAdjacentBlocks(
   134 static long devInstallAddr(
   136             const char *pOwnerName,
   137             epicsAddressType addrType,
   140             volatile void **ppPhysicalAddress);
   148     epicsAddressType addrType,
   150     volatile void **ppLocalAddress)
   153     volatile void *localAddress;
   158     if (!devLibInitFlag) {
   159         status = devLibInit();
   168     status = addrVerify (addrType, busAddr, 4);
   176     status = (*
pdevLibVirtualOS->pDevMapAddr) (addrType, 0, busAddr, 4, &localAddress);
   178         errPrintf (status, __FILE__, __LINE__, 
"%s bus address =0X%X\n",
   186     if (ppLocalAddress) {
   187         *ppLocalAddress = localAddress;
   199     const char *pOwnerName,
   200     epicsAddressType addrType,
   203     volatile void **ppPhysicalAddress)
   208     if (!devLibInitFlag) {
   215     s = addrVerify (addrType, base, size);
   221         return S_dev_lowValue;
   225     errlogPrintf (
"Req Addr 0X%X Size 0X%X\n", base, size);
   228     epicsMutexMustLock(addrListLock);
   229     pRange = (
rangeItem *) ellFirst(&addrFree[addrType]);
   231         if (pRange->
begin > base) {
   234                 errlogPrintf (
"Unable to locate a free block\n");
   235                 devListAddressMap (&addrFree[addrType]);
   239         else if (base + (size - 1) <= pRange->
end) {
   241                 errlogPrintf (
"Found free block Begin 0X%X End 0X%X\n",
   249     epicsMutexUnlock(addrListLock);
   252         report_conflict (addrType, base, size, pOwnerName);
   253         return S_dev_addressOverlap;
   270 static long devInstallAddr (
   272     const char *pOwnerName,
   273     epicsAddressType addrType,
   276     volatile void **ppPhysicalAddress)
   278     volatile void *pPhysicalAddress;
   280     size_t reqEnd = base + (size-1);
   286     if (base < pRange->begin) {
   287         return S_dev_badArgument;
   293     if (reqEnd > pRange->
end) {
   294         return S_dev_badArgument;
   302                 size, &pPhysicalAddress);
   304         errPrintf (status, __FILE__, __LINE__, 
"%s base=0X%X size = 0X%X",
   312     if (ppPhysicalAddress) {
   313         *ppPhysicalAddress = pPhysicalAddress;
   319     if (pRange->
begin == base) {
   320         if (pRange->
end == reqEnd) {
   321             epicsMutexMustLock(addrListLock);
   322             ellDelete(&addrFree[addrType], &pRange->
node);
   323             epicsMutexUnlock(addrListLock);
   324             free ((
void *)pRange);
   327             pRange->
begin = base + size;
   333     else if (pRange->
end == reqEnd) {
   334         pRange->
end = base-1;
   341         pNewRange = (
rangeItem *) calloc (1, 
sizeof(*pRange));
   343             return S_dev_noMemory;
   346         pNewRange->
begin = base + size;
   347         pNewRange->
end = pRange->
end;
   350         pRange->
end = base - 1;
   356         epicsMutexMustLock(addrListLock);
   357         ellInsert(&addrFree[addrType], &pRange->
node, &pNewRange->
node);
   358         epicsMutexUnlock(addrListLock);
   365     pNewRange = (
rangeItem *)calloc (1, 
sizeof(*pRange));
   367         return S_dev_noMemory;
   370     pNewRange->
begin = base;
   371     pNewRange->
end = reqEnd;
   375     devInsertAddress (&addrAlloc[addrType], pNewRange);
   383 static void report_conflict (
   384     epicsAddressType addrType,
   387     const char *pOwnerName
   393             S_dev_addressOverlap,
   396             "%10s 0X%08X - OX%08X Requested by %s",
   399             (
unsigned int)(base+size-1),
   402     pRange = (
rangeItem *) ellFirst(&addrAlloc[addrType]);
   405         if (pRange->
begin <= base + (size-1) && pRange->
end >= base) {
   406             report_conflict_device (addrType, pRange);
   416 static void report_conflict_device(epicsAddressType addrType, 
const rangeItem *pRange)
   419             S_dev_identifyOverlap,
   422             "%10s 0X%08X - 0X%08X Owned by %s",
   424             (
unsigned int)pRange->
begin,
   425             (
unsigned int)pRange->
end,
   433     epicsAddressType addrType,
   435     const char *pOwnerName)
   440     if (!devLibInitFlag) {
   447     s = addrVerify (addrType, baseAddress, 1);
   452     epicsMutexMustLock(addrListLock);
   453     pRange = (
rangeItem *) ellFirst(&addrAlloc[addrType]);
   455         if (pRange->
begin == baseAddress) {
   458         if (pRange->
begin > baseAddress) {
   464     epicsMutexUnlock(addrListLock);
   467         return S_dev_addressNotFound;
   471         s = S_dev_addressOverlap;
   476     "unregister address for %s at 0X%X failed because %s owns it",
   478             (
unsigned int)baseAddress,
   483     epicsMutexMustLock(addrListLock);
   484     ellDelete (&addrAlloc[addrType], &pRange->
node);
   485     epicsMutexUnlock(addrListLock);
   488     devInsertAddress (&addrFree[addrType], pRange);
   489     s = devCombineAdjacentBlocks (&addrFree[addrType], pRange);
   491         errMessage (s, 
"devCombineAdjacentBlocks error");
   501 static long devCombineAdjacentBlocks(
   515         if (pBefore->
end == pRange->
begin-1) {
   516             epicsMutexMustLock(addrListLock);
   518             ellDelete (pRangeList, &pBefore->
node);
   519             epicsMutexUnlock(addrListLock);
   520             free ((
void *)pBefore);
   525         if (pAfter->
begin == pRange->
end+1) {
   526             epicsMutexMustLock(addrListLock);
   527             pRange->
end = pAfter->
end;
   528             ellDelete (pRangeList, &pAfter->
node);
   529             epicsMutexUnlock(addrListLock);
   530             free((
void *)pAfter);
   540 static void devInsertAddress(
   547     epicsMutexMustLock(addrListLock);
   548     pAfter = (
rangeItem *) ellFirst (pRangeList);
   550         if (pNewRange->
end < pAfter->
begin) {
   558         ellInsert (pRangeList, &pBefore->
node, &pNewRange->
node);
   561         ellAdd (pRangeList, &pNewRange->
node);
   563     epicsMutexUnlock(addrListLock);
   570     const char *pOwnerName,
   571     epicsAddressType addrType,
   574     volatile void ** pLocalAddress )
   580     if (!devLibInitFlag) {
   587     s = addrVerify (addrType, 0, size);
   593         return S_dev_lowValue;
   596     epicsMutexMustLock(addrListLock);
   597     pRange = (
rangeItem *) ellFirst (&addrFree[addrType]);
   599         if ((pRange->
end - pRange->
begin) + 1 >= size){
   612     epicsMutexUnlock(addrListLock);
   615         s = S_dev_deviceDoesNotFit;
   620     s = devInstallAddr (pRange, pOwnerName, addrType, base,
   621             size, pLocalAddress);
   631 static long addrVerify(epicsAddressType addrType, 
size_t base, 
size_t size)
   634         return S_dev_uknAddrType;
   638         return addrFail[addrType];
   641     if (size-1 > addrLast[addrType]) {
   642         return addrFail[addrType];
   645     if (base > addrLast[addrType]) {
   646         return addrFail[addrType];
   649     if (size - 1 > addrLast[addrType] - base) {
   650         return addrFail[addrType];
   659 static long devLibInit (
void)
   665     if(devLibInitFlag) 
return(
SUCCESS);
   667         epicsPrintf (
"pdevLibVirtualOS is NULL\n");
   668         return S_dev_internal;
   671     if (NELEMENTS(addrAlloc) != NELEMENTS(addrFree)) {
   672         return S_dev_internal;
   675     addrListLock = epicsMutexMustCreate();
   677     epicsMutexMustLock(addrListLock);
   678     for (i=0; i<NELEMENTS(addrAlloc); i++) {
   679         ellInit (&addrAlloc[i]);
   680         ellInit (&addrFree[i]);
   683     for (i=0; i<NELEMENTS(addrAlloc); i++) {
   684         pRange = (
rangeItem *) malloc (
sizeof(*pRange));
   686             return S_dev_noMemory;
   691         pRange->
end = addrLast[i];
   692         ellAdd (&addrFree[i], &pRange->
node);
   694     epicsMutexUnlock(addrListLock);
   695     devLibInitFlag = TRUE;
   704     return devListAddressMap(addrAlloc);
   710 static long devListAddressMap(ELLLIST *pRangeList)
   715     if (!devLibInitFlag) {
   716         long s = devLibInit ();
   723     epicsMutexMustLock(addrListLock);
   724     for (i=0; i<NELEMENTS(addrAlloc); i++) {
   725         pri = (
rangeItem *) ellFirst(&pRangeList[i]);
   730             errlogPrintf (
"\t0X%0*lX - 0X%0*lX physical base %p %s\n",
   732                 (
unsigned long) pri->
begin,
   734                 (
unsigned long) pri->
end,
   740     epicsMutexUnlock(addrListLock);
   753 static long blockFind (
   754     epicsAddressType addrType,
   772     mask = devCreateMask (alignment);
   773     newBase = pRange->
begin;
   774     if ( mask & newBase ) {
   779     if ( requestSize == 0) {
   780         return S_dev_badRequest;
   786     newSize = requestSize;
   787     if (mask & newSize) {
   792     if (pRange->
end - pRange->
begin + 1 < newSize) {
   793         return S_dev_badRequest;
   797     while (bb <= (pRange->
end + 1) - newSize) {
   809 #include <epicsExport.h> 
long devAddressMap2(void)
 
volatile void * pPhysical
 
epicsExportRegistrar(devReplaceVirtualOS)
 
long devRegisterAddress2(const char *pOwnerName, epicsAddressType addrType, size_t base, size_t size, volatile void **ppPhysicalAddress)
 
devLibVirtualOS * pdevLibVirtualOS
 
long devUnregisterAddress2(epicsAddressType addrType, size_t baseAddress, const char *pOwnerName)
 
devLibVirtualOS * pdevLibVME2
 
void devReplaceVirtualOS(void)
 
long devNoResponseProbe(epicsAddressType addrType, size_t base, size_t size)
 
long devBusToLocalAddr2(epicsAddressType addrType, size_t busAddr, volatile void **ppLocalAddress)
 
long devAllocAddress2(const char *pOwnerName, epicsAddressType addrType, size_t size, unsigned alignment, volatile void **pLocalAddress)
 
const char * epicsAddressTypeName[]
 
const char * epicsAddressTypeName2[]