Merge lp:~mdavidsaver/epics-base/devlib-cleanup into lp:~epics-core/epics-base/3.14

Proposed by mdavidsaver
Status: Merged
Approved by: Ralph Lange
Approved revision: 12083
Merge reported by: Andrew Johnson
Merged at revision: not available
Proposed branch: lp:~mdavidsaver/epics-base/devlib-cleanup
Merge into: lp:~epics-core/epics-base/3.14
Diff against target: 5089 lines (+2492/-2392)
15 files modified
documentation/RELEASE_NOTES.html (+13/-0)
src/libCom/Makefile (+4/-2)
src/libCom/osi/devLib.c (+0/-1078)
src/libCom/osi/devLib.h (+0/-444)
src/libCom/osi/devLibVME.c (+1159/-0)
src/libCom/osi/devLibVME.h (+312/-0)
src/libCom/osi/devLibVMEImpl.h (+104/-0)
src/libCom/osi/os/RTEMS/devLibOSD.c (+0/-350)
src/libCom/osi/os/RTEMS/devLibVMEOSD.c (+366/-0)
src/libCom/osi/os/cygwin32/devLibOSD.c (+0/-15)
src/libCom/osi/os/cygwin32/devLibVMEOSD.c (+15/-0)
src/libCom/osi/os/default/devLibOSD.c (+0/-17)
src/libCom/osi/os/default/devLibVMEOSD.c (+17/-0)
src/libCom/osi/os/vxWorks/devLibOSD.c (+0/-486)
src/libCom/osi/os/vxWorks/devLibVMEOSD.c (+502/-0)
To merge this branch: bzr merge lp:~mdavidsaver/epics-base/devlib-cleanup
Reviewer Review Type Date Requested Status
Eric Norum Approve
Ralph Lange Approve
Andrew Johnson Approve
Review via email: mp+25966@code.launchpad.net

Commit message

Cleanup of devLib

Description of the change

Cleanup of devLib

devLib.h split up:

  devLib.h - General macros and error codes.
  devLibVME.h - VME user API (also ISA)
  devLibVMEImpl.h - VME function pointer table defintion

For compatibility including devLib.h will implicitly include the other two.

API changes

  Remove unimplemented PCI functions.

To post a comment you must log in.
Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Since the diff on the merge proposal page isn't useful I would suggest looking at the individual commits on the branch.

https://code.launchpad.net/~mdavidsaver/epics-base/devlib-cleanup

Revision history for this message
Andrew Johnson (anj) wrote :

Hi Michael,

Please ensure all files have an appropriate Copyright header, I at least one file is missing this completely and the other files don't currently have Brookhaven listed as a Copyright holder.
Delete the old RCS expanded $Id$ keywords; you must have taken your originals from an official EPICS Base release since they are all missing the $ signs. Bazaar only supports keywords with a plugin, but $Id$ is not one of those anyway, so we'll probably drop all the $Id$ keywords currently in Base.

I haven't actually looked at the code yet...

12081. By mdavidsaver on 2010-05-26

copyright boilerplate for devLibVME

Revision history for this message
Ralph Lange (ralph-lange) wrote :

Hi,

the changes look good to me.

Only a minor issue:
In RTEMS/devLibVMEOSD.c one function of the virtual table is named "rtems...", all the others and the table itself are "rtms..." - what's the rationale behind that?

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Andrew. Copyrights added.

Ralph. devLibVMEOSD.c was devLibOSD.c. The changes I made to this file date from last year's codeathon. rtemsDevInterruptInUseVME is the function I added. I can't remember why I didn't fix the others then. In fact I don't remember even noticing! I will now though.

12082. By mdavidsaver on 2010-05-27

fix typo in rtems internal function names

Not externally visible so no reason not to fix

12083. By mdavidsaver on 2010-05-28

include compatibility definition of pdevLibVirtualOS

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

I have verified that synApps 5.5 will compile against these changes on Linux and RTEMS.

The only problem I found was that several of the motor module drivers are calling pdevLibVirtualOS->pDevConnectInterruptVME directly. I added an #define of pdevLibVirtualOS using the new name.

Revision history for this message
Andrew Johnson (anj) wrote :

Michael: I'm going to add a separate comment for each issue I find.

I realize you didn't originate this commonly-used construct from devLib.c, but lazy-init done this way is not thread-safe on an SMP machine (e.g. a Linux PC with a PCI-VME bridge):
    if (!devLibInitFlag) {
        status = devLibInit();
        if (status) {
            return status;
        }
    }
It needs to be replaced by a call to epicsThreadOnce() everywhere it occurs, and you'll have to work out how to handle the error return (if it's still necessary).

Revision history for this message
Andrew Johnson (anj) wrote :

Bazaar fully supports file renames, but (unlike git) it doesn't detect them automatically, you have to do an explicit 'bzr mv' for it to know about them. Unfortunately Patch 07/12 appears to have used 'bzr rm' + 'bzr add' instead, so the history record will not be continuous for these files. It's not worth spending time fixing this now (CVS caused the same issues in the past), but please try and use it in the future if you can.

Revision history for this message
Andrew Johnson (anj) wrote :

Looks good. I'm going to approve this now and leave it up to you when to fix the epicsThreadOnce() issue above; we've coped with it so far without much problem, so I don't see it as a blocker for this work.

review: Approve
Revision history for this message
mdavidsaver (mdavidsaver) wrote :

> Looks good. I'm going to approve this now and leave it up to you when to fix
> the epicsThreadOnce() issue above; we've coped with it so far without much
> problem, so I don't see it as a blocker for this work.

This does need to be fixed. But in the interest of not having to retest this branch I'd like to do the initialization fix separately.

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Andrew,

What additional review is needed before this branch can be merged?

Revision history for this message
Andrew Johnson (anj) wrote :

I was hoping for Eric's formal OK since this has RTEMS-specific changes in it and he is named as a reviewer. Ralph already voiced his approval above, although he didn't actually set his comment to Approve.

Eric, if you get this could you take a quick look at it, or let us know you're too busy (I didn't see anything problematic, but I'd like to stick with the formalities rather than going over your head).

Revision history for this message
Ralph Lange (ralph-lange) wrote :

Yup. Sure looks good enough to me.

review: Approve
Revision history for this message
Eric Norum (wenorum) wrote :

Seems reasonable at a quick glance. I don't have any hardware handy right now to test this, though.
Approved -- and sorry for the delay.

On Jul 1, 2010, at 8:22 AM, Andrew Johnson wrote:

> I was hoping for Eric's formal OK since this has RTEMS-specific changes in it and he is named as a reviewer. Ralph already voiced his approval above, although he didn't actually set his comment to Approve.
>
> Eric, if you get this could you take a quick look at it, or let us know you're too busy (I didn't see anything problematic, but I'd like to stick with the formalities rather than going over your head).
> --
> https://code.launchpad.net/~mdavidsaver/epics-base/devlib-cleanup/+merge/25966
> You are requested to review the proposed merge of lp:~mdavidsaver/epics-base/devlib-cleanup into lp:epics-base.

--
Eric Norum
<email address hidden>

Revision history for this message
Eric Norum (wenorum) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'documentation/RELEASE_NOTES.html'
2--- documentation/RELEASE_NOTES.html 2010-04-26 22:16:06 +0000
3+++ documentation/RELEASE_NOTES.html 2010-05-28 11:06:32 +0000
4@@ -12,6 +12,19 @@
5 <h2 align="center">Changes between 3.14.11 and 3.14.12</h2>
6 <!-- Insert new items immediately below here ... -->
7
8+<h4>devLib cleanup</h4>
9+
10+<ul>
11+<li>Add VME connect/disconnect IRQ calls to the "virtual os" table</li>
12+<li>It is now possible to compile all devLib code on targets without runtime support</li>
13+<li>All internal functions are made static. Some were not before.</li>
14+<li>Move VME calls to devLibVME.h. devLib.h contains general defintions and error codes.</li>
15+<li>For compatibility devLib.h includes devLibVME.h unless the macro NO_DEVLIB_COMPAT is defined.</li>
16+<li>The "virtual os" table is renamed from pdevLibVirtualOS to pdevLibVME to reflect the fact
17+that other bus types would use seperate tables.</li>
18+<li>The "virtual os" table API has been moved to a seperate header devLibVMEImpl.h.</li>
19+</ul>
20+
21 <h4>Rewrite epicsThreadOnce()</h4>
22
23 <p>Michael Davidsaver suggested a better implementation of epicsThreadOnce()
24
25=== modified file 'src/libCom/Makefile'
26--- src/libCom/Makefile 2009-04-02 21:15:26 +0000
27+++ src/libCom/Makefile 2010-05-28 11:06:32 +0000
28@@ -192,6 +192,8 @@
29 INC += epicsGetopt.h
30
31 INC += devLib.h
32+INC += devLibVME.h
33+INC += devLibVMEImpl.h
34 INC += osdVME.h
35
36 SRCS += epicsThread.cpp
37@@ -230,8 +232,8 @@
38 SRCS += osdNetIntf.c
39 SRCS += osdMessageQueue.c
40
41-SRCS += devLib.c
42-SRCS += devLibOSD.c
43+SRCS += devLibVME.c
44+SRCS += devLibVMEOSD.c
45
46 SRC_DIRS += $(LIBCOM)/taskwd
47 INC += taskwd.h
48
49=== removed file 'src/libCom/osi/devLib.c'
50--- src/libCom/osi/devLib.c 2009-07-09 16:37:24 +0000
51+++ src/libCom/osi/devLib.c 1970-01-01 00:00:00 +0000
52@@ -1,1078 +0,0 @@
53-/*************************************************************************\
54-* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
55-* National Laboratory.
56-* Copyright (c) 2002 The Regents of the University of California, as
57-* Operator of Los Alamos National Laboratory.
58-* EPICS BASE is distributed subject to a Software License Agreement found
59-* in file LICENSE that is included with this distribution.
60-\*************************************************************************/
61-/* devLib.c - support for allocation of common device resources */
62-/* $Id$ */
63-
64-/*
65- * Original Author: Marty Kraimer
66- * Author: Jeff Hill
67- * Date: 03-10-93
68- *
69- * NOTES:
70- * .01 06-14-93 joh needs devAllocInterruptVector() routine
71- */
72-
73-static const char sccsID[] = "@(#) $Id$";
74-
75-#include <string.h>
76-#include <stdio.h>
77-#include <stdlib.h>
78-
79-#define epicsExportSharedSymbols
80-#include "dbDefs.h"
81-#include "epicsMutex.h"
82-#include "errlog.h"
83-#include "ellLib.h"
84-#include "devLib.h"
85-
86-static ELLLIST addrAlloc[atLast];
87-static ELLLIST addrFree[atLast];
88-
89-static size_t addrLast[atLast] = {
90- 0xffff,
91- 0xffffff,
92- 0xffffffff,
93- 0xffffff,
94- 0xffffff,
95- };
96-
97-static unsigned addrHexDig[atLast] = {
98- 4,
99- 6,
100- 8,
101- 6,
102- 6
103- };
104-
105-static long addrFail[atLast] = {
106- S_dev_badA16,
107- S_dev_badA24,
108- S_dev_badA32,
109- S_dev_badISA,
110- S_dev_badCRCSR
111- };
112-
113-static epicsMutexId addrListLock;
114-static char devLibInitFlag;
115-
116-const char *epicsAddressTypeName[]
117- = {
118- "VME A16",
119- "VME A24",
120- "VME A32",
121- "ISA",
122- "VME CR/CSR"
123- };
124-
125-typedef struct{
126- ELLNODE node;
127- const char *pOwnerName;
128- volatile void *pPhysical;
129- /*
130- * first, last is used here instead of base, size
131- * so that we can store a block that is the maximum size
132- * available in type size_t
133- */
134- size_t begin;
135- size_t end;
136-}rangeItem;
137-
138-/*
139- * These routines are not exported
140- */
141-
142-static long devLibInit(void);
143-
144-static long addrVerify(
145- epicsAddressType addrType,
146- size_t base,
147- size_t size);
148-
149-static long blockFind (
150- epicsAddressType addrType,
151- const rangeItem *pRange,
152- /* size needed */
153- size_t requestSize,
154- /* n ls bits zero in base addr */
155- unsigned alignment,
156- /* base address found */
157- size_t *pFirst);
158-
159-static void report_conflict(
160- epicsAddressType addrType,
161- size_t base,
162- size_t size,
163- const char *pOwnerName);
164-
165-static void report_conflict_device(
166- epicsAddressType addrType,
167- const rangeItem *pRange);
168-
169-static void devInsertAddress(
170- ELLLIST *pRangeList,
171- rangeItem *pNewRange);
172-
173-static long devListAddressMap(
174- ELLLIST *pRangeList);
175-
176-static long devCombineAdjacentBlocks(
177- ELLLIST *pRangeList,
178- rangeItem *pRange);
179-
180-static long devInstallAddr(
181- rangeItem *pRange, /* item on the free list to be split */
182- const char *pOwnerName,
183- epicsAddressType addrType,
184- size_t base,
185- size_t size,
186- volatile void **ppPhysicalAddress);
187-
188-#define SUCCESS 0
189-
190-/*
191- * devBusToLocalAddr()
192- */
193-long devBusToLocalAddr(
194- epicsAddressType addrType,
195- size_t busAddr,
196- volatile void **ppLocalAddress)
197-{
198- long status;
199- volatile void *localAddress;
200-
201- /*
202- * Make sure that devLib has been intialized
203- */
204- if (!devLibInitFlag) {
205- status = devLibInit();
206- if(status){
207- return status;
208- }
209- }
210-
211- /*
212- * Make sure we have a valid bus address
213- */
214- status = addrVerify (addrType, busAddr, 4);
215- if (status) {
216- return status;
217- }
218-
219- /*
220- * Call the virtual os routine to map the bus address to a CPU address
221- */
222- status = (*pdevLibVirtualOS->pDevMapAddr) (addrType, 0, busAddr, 4, &localAddress);
223- if (status) {
224- errPrintf (status, __FILE__, __LINE__, "%s bus address =0X%X\n",
225- epicsAddressTypeName[addrType], (unsigned int)busAddr);
226- return status;
227- }
228-
229- /*
230- * Return the local CPU address if the pointer is supplied
231- */
232- if (ppLocalAddress) {
233- *ppLocalAddress = localAddress;
234- }
235-
236- return SUCCESS;
237-
238-}/*end devBusToLocalAddr()*/
239-
240-
241-/*
242- * devRegisterAddress()
243- */
244-long devRegisterAddress(
245- const char *pOwnerName,
246- epicsAddressType addrType,
247- size_t base,
248- size_t size,
249- volatile void **ppPhysicalAddress)
250-{
251- rangeItem *pRange;
252- long s;
253-
254- if (!devLibInitFlag) {
255- s = devLibInit();
256- if(s){
257- return s;
258- }
259- }
260-
261- s = addrVerify (addrType, base, size);
262- if (s) {
263- return s;
264- }
265-
266- if (size == 0) {
267- return S_dev_lowValue;
268- }
269-
270-#ifdef DEBUG
271- printf ("Req Addr 0X%X Size 0X%X\n", base, size);
272-#endif
273-
274- epicsMutexMustLock(addrListLock);
275- pRange = (rangeItem *) ellFirst(&addrFree[addrType]);
276- while (TRUE) {
277- if (pRange->begin > base) {
278- pRange = NULL;
279-# ifdef DEBUG
280- printf ("Unable to locate a free block\n");
281- devListAddressMap (&addrFree[addrType]);
282-# endif
283- break;
284- }
285- else if (base + (size - 1) <= pRange->end) {
286-# ifdef DEBUG
287- printf ("Found free block Begin 0X%X End 0X%X\n",
288- pRange->begin, pRange->end);
289-# endif
290- break;
291- }
292-
293- pRange = (rangeItem *) ellNext (&pRange->node);
294- }
295- epicsMutexUnlock(addrListLock);
296-
297- if (pRange==NULL) {
298- report_conflict (addrType, base, size, pOwnerName);
299- return S_dev_addressOverlap;
300- }
301-
302- s = devInstallAddr(
303- pRange, /* item on the free list to be split */
304- pOwnerName,
305- addrType,
306- base,
307- size,
308- ppPhysicalAddress);
309-
310- return s;
311-}
312-
313-/*
314- * devReadProbe()
315- *
316- * a bus error safe "wordSize" read at the specified address which returns
317- * unsuccessful status if the device isnt present
318- */
319-long devReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue)
320-{
321- long status;
322-
323- if (!devLibInitFlag) {
324- status = devLibInit();
325- if (status) {
326- return status;
327- }
328- }
329-
330- return (*pdevLibVirtualOS->pDevReadProbe) (wordSize, ptr, pValue);
331-}
332-
333-/*
334- * devWriteProbe
335- *
336- * a bus error safe "wordSize" write at the specified address which returns
337- * unsuccessful status if the device isnt present
338- */
339-long devWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue)
340-{
341- long status;
342-
343- if (!devLibInitFlag) {
344- status = devLibInit();
345- if (status) {
346- return status;
347- }
348- }
349-
350- return (*pdevLibVirtualOS->pDevWriteProbe) (wordSize, ptr, pValue);
351-}
352-
353-/*
354- * devInstallAddr()
355- */
356-static long devInstallAddr (
357- rangeItem *pRange, /* item on the free list to be split */
358- const char *pOwnerName,
359- epicsAddressType addrType,
360- size_t base,
361- size_t size,
362- volatile void **ppPhysicalAddress)
363-{
364- volatile void *pPhysicalAddress;
365- rangeItem *pNewRange;
366- size_t reqEnd = base + (size-1);
367- long status;
368-
369- /*
370- * does it start below the specified block
371- */
372- if (base < pRange->begin) {
373- return S_dev_badArgument;
374- }
375-
376- /*
377- * does it end above the specified block
378- */
379- if (reqEnd > pRange->end) {
380- return S_dev_badArgument;
381- }
382-
383- /*
384- * always map through the virtual os in case the memory
385- * management is set up there
386- */
387- status = (*pdevLibVirtualOS->pDevMapAddr) (addrType, 0, base,
388- size, &pPhysicalAddress);
389- if (status) {
390- errPrintf (status, __FILE__, __LINE__, "%s base=0X%X size = 0X%X",
391- epicsAddressTypeName[addrType], (unsigned int)base, (unsigned int)size);
392- return status;
393- }
394-
395- /*
396- * set the callers variable if the pointer is supplied
397- */
398- if (ppPhysicalAddress) {
399- *ppPhysicalAddress = pPhysicalAddress;
400- }
401-
402- /*
403- * does it start at the beginning of the block
404- */
405- if (pRange->begin == base) {
406- if (pRange->end == reqEnd) {
407- epicsMutexMustLock(addrListLock);
408- ellDelete(&addrFree[addrType], &pRange->node);
409- epicsMutexUnlock(addrListLock);
410- free ((void *)pRange);
411- }
412- else {
413- pRange->begin = base + size;
414- }
415- }
416- /*
417- * does it end at the end of the block
418- */
419- else if (pRange->end == reqEnd) {
420- pRange->end = base-1;
421- }
422- /*
423- * otherwise split the item on the free list
424- */
425- else {
426-
427- pNewRange = (rangeItem *) calloc (1, sizeof(*pRange));
428- if(!pNewRange){
429- return S_dev_noMemory;
430- }
431-
432- pNewRange->begin = base + size;
433- pNewRange->end = pRange->end;
434- pNewRange->pOwnerName = "<fragmented block>";
435- pNewRange->pPhysical = NULL;
436- pRange->end = base - 1;
437-
438- /*
439- * add the node after the old item on the free list
440- * (blocks end up ordered by address)
441- */
442- epicsMutexMustLock(addrListLock);
443- ellInsert(&addrFree[addrType], &pRange->node, &pNewRange->node);
444- epicsMutexUnlock(addrListLock);
445- }
446-
447- /*
448- * allocate a new address range entry and add it to
449- * the list
450- */
451- pNewRange = (rangeItem *)calloc (1, sizeof(*pRange));
452- if (!pNewRange) {
453- return S_dev_noMemory;
454- }
455-
456- pNewRange->begin = base;
457- pNewRange->end = reqEnd;
458- pNewRange->pOwnerName = pOwnerName;
459- pNewRange->pPhysical = pPhysicalAddress;
460-
461- devInsertAddress (&addrAlloc[addrType], pNewRange);
462-
463- return SUCCESS;
464-}
465-
466-/*
467- * report_conflict()
468- */
469-static void report_conflict (
470- epicsAddressType addrType,
471- size_t base,
472- size_t size,
473- const char *pOwnerName
474-)
475-{
476- const rangeItem *pRange;
477-
478- errPrintf (
479- S_dev_addressOverlap,
480- __FILE__,
481- __LINE__,
482- "%10s 0X%08X - OX%08X Requested by %s",
483- epicsAddressTypeName[addrType],
484- (unsigned int)base,
485- (unsigned int)(base+size-1),
486- pOwnerName);
487-
488- pRange = (rangeItem *) ellFirst(&addrAlloc[addrType]);
489- while (pRange) {
490-
491- if (pRange->begin <= base + (size-1) && pRange->end >= base) {
492- report_conflict_device (addrType, pRange);
493- }
494-
495- pRange = (rangeItem *) pRange->node.next;
496- }
497-}
498-
499-/*
500- * report_conflict_device()
501- */
502-static void report_conflict_device(epicsAddressType addrType, const rangeItem *pRange)
503-{
504- errPrintf (
505- S_dev_identifyOverlap,
506- __FILE__,
507- __LINE__,
508- "%10s 0X%08X - 0X%08X Owned by %s",
509- epicsAddressTypeName[addrType],
510- (unsigned int)pRange->begin,
511- (unsigned int)pRange->end,
512- pRange->pOwnerName);
513-}
514-
515-/*
516- * devUnregisterAddress()
517- */
518-long devUnregisterAddress(
519- epicsAddressType addrType,
520- size_t baseAddress,
521- const char *pOwnerName)
522-{
523- rangeItem *pRange;
524- int s;
525-
526- if (!devLibInitFlag) {
527- s = devLibInit();
528- if(s) {
529- return s;
530- }
531- }
532-
533- s = addrVerify (addrType, baseAddress, 1);
534- if (s != SUCCESS) {
535- return s;
536- }
537-
538- epicsMutexMustLock(addrListLock);
539- pRange = (rangeItem *) ellFirst(&addrAlloc[addrType]);
540- while (pRange) {
541- if (pRange->begin == baseAddress) {
542- break;
543- }
544- if (pRange->begin > baseAddress) {
545- pRange = NULL;
546- break;
547- }
548- pRange = (rangeItem *) ellNext(&pRange->node);
549- }
550- epicsMutexUnlock(addrListLock);
551-
552- if (!pRange) {
553- return S_dev_addressNotFound;
554- }
555-
556- if (strcmp(pOwnerName,pRange->pOwnerName)) {
557- s = S_dev_addressOverlap;
558- errPrintf (
559- s,
560- __FILE__,
561- __LINE__,
562- "unregister address for %s at 0X%X failed because %s owns it",
563- pOwnerName,
564- (unsigned int)baseAddress,
565- pRange->pOwnerName);
566- return s;
567- }
568-
569- epicsMutexMustLock(addrListLock);
570- ellDelete (&addrAlloc[addrType], &pRange->node);
571- epicsMutexUnlock(addrListLock);
572-
573- pRange->pOwnerName = "<released fragment>";
574- devInsertAddress (&addrFree[addrType], pRange);
575- s = devCombineAdjacentBlocks (&addrFree[addrType], pRange);
576- if(s){
577- errMessage (s, "devCombineAdjacentBlocks error");
578- return s;
579- }
580-
581- return SUCCESS;
582-}
583-
584-/*
585- * devCombineAdjacentBlocks()
586- */
587-static long devCombineAdjacentBlocks(
588- ELLLIST *pRangeList,
589- rangeItem *pRange)
590-{
591- rangeItem *pBefore;
592- rangeItem *pAfter;
593-
594- pBefore = (rangeItem *) ellPrevious (&pRange->node);
595- pAfter = (rangeItem *) ellNext (&pRange->node);
596-
597- /*
598- * combine adjacent blocks
599- */
600- if (pBefore) {
601- if (pBefore->end == pRange->begin-1) {
602- epicsMutexMustLock(addrListLock);
603- pRange->begin = pBefore->begin;
604- ellDelete (pRangeList, &pBefore->node);
605- epicsMutexUnlock(addrListLock);
606- free ((void *)pBefore);
607- }
608- }
609-
610- if (pAfter) {
611- if (pAfter->begin == pRange->end+1) {
612- epicsMutexMustLock(addrListLock);
613- pRange->end = pAfter->end;
614- ellDelete (pRangeList, &pAfter->node);
615- epicsMutexUnlock(addrListLock);
616- free((void *)pAfter);
617- }
618- }
619-
620- return SUCCESS;
621-}
622-
623-/*
624- * devInsertAddress()
625- */
626-static void devInsertAddress(
627-ELLLIST *pRangeList,
628-rangeItem *pNewRange)
629-{
630- rangeItem *pBefore;
631- rangeItem *pAfter;
632-
633- epicsMutexMustLock(addrListLock);
634- pAfter = (rangeItem *) ellFirst (pRangeList);
635- while (pAfter) {
636- if (pNewRange->end < pAfter->begin) {
637- break;
638- }
639- pAfter = (rangeItem *) ellNext (&pAfter->node);
640- }
641-
642- if (pAfter) {
643- pBefore = (rangeItem *) ellPrevious (&pAfter->node);
644- ellInsert (pRangeList, &pBefore->node, &pNewRange->node);
645- }
646- else {
647- ellAdd (pRangeList, &pNewRange->node);
648- }
649- epicsMutexUnlock(addrListLock);
650-}
651-
652-/*
653- * devAllocAddress()
654- */
655-long devAllocAddress(
656- const char *pOwnerName,
657- epicsAddressType addrType,
658- size_t size,
659- unsigned alignment, /* n ls bits zero in base addr*/
660- volatile void ** pLocalAddress )
661-{
662- int s;
663- rangeItem *pRange;
664- size_t base = 0;
665-
666- if (!devLibInitFlag) {
667- s = devLibInit();
668- if(s){
669- return s;
670- }
671- }
672-
673- s = addrVerify (addrType, 0, size);
674- if(s){
675- return s;
676- }
677-
678- if (size == 0) {
679- return S_dev_lowValue;
680- }
681-
682- epicsMutexMustLock(addrListLock);
683- pRange = (rangeItem *) ellFirst (&addrFree[addrType]);
684- while (pRange) {
685- if ((pRange->end - pRange->begin) + 1 >= size){
686- s = blockFind (
687- addrType,
688- pRange,
689- size,
690- alignment,
691- &base);
692- if (s==SUCCESS) {
693- break;
694- }
695- }
696- pRange = (rangeItem *) pRange->node.next;
697- }
698- epicsMutexUnlock(addrListLock);
699-
700- if(!pRange){
701- s = S_dev_deviceDoesNotFit;
702- errMessage(s, epicsAddressTypeName[addrType]);
703- return s;
704- }
705-
706- s = devInstallAddr (pRange, pOwnerName, addrType, base,
707- size, pLocalAddress);
708-
709- return s;
710-}
711-
712-/*
713- * addrVerify()
714- *
715- * care has been taken here not to overflow type size_t
716- */
717-static long addrVerify(epicsAddressType addrType, size_t base, size_t size)
718-{
719- if (addrType>=atLast) {
720- return S_dev_uknAddrType;
721- }
722-
723- if (size == 0) {
724- return addrFail[addrType];
725- }
726-
727- if (size-1 > addrLast[addrType]) {
728- return addrFail[addrType];
729- }
730-
731- if (base > addrLast[addrType]) {
732- return addrFail[addrType];
733- }
734-
735- if (size - 1 > addrLast[addrType] - base) {
736- return addrFail[addrType];
737- }
738-
739- return SUCCESS;
740-}
741-
742-/*
743- * devLibInit()
744- */
745-static long devLibInit (void)
746-{
747- rangeItem *pRange;
748- int i;
749-
750-
751- if(devLibInitFlag) return(SUCCESS);
752- if(!pdevLibVirtualOS) {
753- epicsPrintf ("pdevLibVirtualOS is NULL\n");
754- return S_dev_internal;
755- }
756-
757- if (NELEMENTS(addrAlloc) != NELEMENTS(addrFree)) {
758- return S_dev_internal;
759- }
760-
761- addrListLock = epicsMutexMustCreate();
762-
763- epicsMutexMustLock(addrListLock);
764- for (i=0; i<NELEMENTS(addrAlloc); i++) {
765- ellInit (&addrAlloc[i]);
766- ellInit (&addrFree[i]);
767- }
768-
769- for (i=0; i<NELEMENTS(addrAlloc); i++) {
770- pRange = (rangeItem *) malloc (sizeof(*pRange));
771- if (!pRange) {
772- return S_dev_noMemory;
773- }
774- pRange->pOwnerName = "<Vacant>";
775- pRange->pPhysical = NULL;
776- pRange->begin = 0;
777- pRange->end = addrLast[i];
778- ellAdd (&addrFree[i], &pRange->node);
779- }
780- epicsMutexUnlock(addrListLock);
781- devLibInitFlag = TRUE;
782- return pdevLibVirtualOS->pDevInit();
783-}
784-
785-/*
786- * devAddressMap()
787- */
788-long devAddressMap(void)
789-{
790- return devListAddressMap(addrAlloc);
791-}
792-
793-/*
794- * devListAddressMap()
795- */
796-static long devListAddressMap(ELLLIST *pRangeList)
797-{
798- rangeItem *pri;
799- int i;
800- long s;
801-
802- if (!devLibInitFlag) {
803- s = devLibInit ();
804- if (s) {
805- return s;
806- }
807- }
808-
809- epicsMutexMustLock(addrListLock);
810- for (i=0; i<NELEMENTS(addrAlloc); i++) {
811- pri = (rangeItem *) ellFirst(&pRangeList[i]);
812- if (pri) {
813- printf ("%s Address Map\n", epicsAddressTypeName[i]);
814- }
815- while (pri) {
816- printf ("\t0X%0*lX - 0X%0*lX physical base %p %s\n",
817- addrHexDig[i],
818- (unsigned long) pri->begin,
819- addrHexDig[i],
820- (unsigned long) pri->end,
821- pri->pPhysical,
822- pri->pOwnerName);
823- pri = (rangeItem *) ellNext (&pri->node);
824- }
825- }
826- epicsMutexUnlock(addrListLock);
827-
828- return SUCCESS;
829-}
830-
831-
832-/*
833- *
834- * blockFind()
835- *
836- * Find unoccupied block in a large block
837- *
838- */
839-static long blockFind (
840- epicsAddressType addrType,
841- const rangeItem *pRange,
842- /* size needed */
843- size_t requestSize,
844- /* n ls bits zero in base addr */
845- unsigned alignment,
846- /* base address found */
847- size_t *pBase)
848-{
849- int s = SUCCESS;
850- size_t bb;
851- size_t mask;
852- size_t newBase;
853- size_t newSize;
854-
855- /*
856- * align the block base
857- */
858- mask = devCreateMask (alignment);
859- newBase = pRange->begin;
860- if ( mask & newBase ) {
861- newBase |= mask;
862- newBase++;
863- }
864-
865- if ( requestSize == 0) {
866- return S_dev_badRequest;
867- }
868-
869- /*
870- * align size of block
871- */
872- newSize = requestSize;
873- if (mask & newSize) {
874- newSize |= mask;
875- newSize++;
876- }
877-
878- if (pRange->end - pRange->begin + 1 < newSize) {
879- return S_dev_badRequest;
880- }
881-
882- bb = pRange->begin;
883- while (bb <= (pRange->end + 1) - newSize) {
884- s = devNoResponseProbe (addrType, bb, newSize);
885- if (s==SUCCESS) {
886- *pBase = bb;
887- return SUCCESS;
888- }
889- bb += newSize;
890- }
891-
892- return s;
893-}
894-
895-/*
896- * devNoResponseProbe()
897- */
898-long devNoResponseProbe (epicsAddressType addrType,
899- size_t base, size_t size)
900-{
901- volatile void *pPhysical;
902- size_t probe;
903- size_t byteNo;
904- unsigned wordSize;
905- union {
906- char charWord;
907- short shortWord;
908- int intWord;
909- long longWord;
910- }allWordSizes;
911- long s;
912-
913- if (!devLibInitFlag) {
914- s = devLibInit();
915- if (s) {
916- return s;
917- }
918- }
919-
920- byteNo = 0;
921- while (byteNo < size) {
922-
923- probe = base + byteNo;
924-
925- /*
926- * for all word sizes
927- */
928- for (wordSize=1; wordSize<=sizeof(allWordSizes); wordSize <<= 1) {
929- /*
930- * only check naturally aligned words
931- */
932- if ( (probe&(wordSize-1)) != 0 ) {
933- break;
934- }
935-
936- if (byteNo+wordSize>size) {
937- break;
938- }
939-
940- /*
941- * every byte in the block must
942- * map to a physical address
943- */
944- s = (*pdevLibVirtualOS->pDevMapAddr) (addrType, 0, probe, wordSize, &pPhysical);
945- if (s!=SUCCESS) {
946- return s;
947- }
948-
949- /*
950- * verify that no device is present
951- */
952- s = (*pdevLibVirtualOS->pDevReadProbe)(wordSize, pPhysical, &allWordSizes);
953- if (s==SUCCESS) {
954- return S_dev_addressOverlap;
955- }
956- }
957- byteNo++;
958- }
959- return SUCCESS;
960-}
961-
962-/*
963- * devConnectInterrupt ()
964- *
965- * !! DEPRECATED !!
966- */
967-long devConnectInterrupt(
968-epicsInterruptType intType,
969-unsigned vectorNumber,
970-void (*pFunction)(void *),
971-void *parameter)
972-{
973- long status;
974-
975- if (!devLibInitFlag) {
976- status = devLibInit();
977- if (status) {
978- return status;
979- }
980- }
981-
982- switch(intType){
983- case intVME:
984- case intVXI:
985- return (*pdevLibVirtualOS->pDevConnectInterruptVME) (vectorNumber,
986- pFunction, parameter);
987- default:
988- return S_dev_uknIntType;
989- }
990-}
991-
992-/*
993- *
994- * devDisconnectInterrupt()
995- *
996- * !! DEPRECATED !!
997- */
998-long devDisconnectInterrupt(
999-epicsInterruptType intType,
1000-unsigned vectorNumber,
1001-void (*pFunction)(void *)
1002-)
1003-{
1004- long status;
1005-
1006- if (!devLibInitFlag) {
1007- status = devLibInit();
1008- if (status) {
1009- return status;
1010- }
1011- }
1012-
1013- switch(intType){
1014- case intVME:
1015- case intVXI:
1016- return (*pdevLibVirtualOS->pDevDisconnectInterruptVME) (vectorNumber,
1017- pFunction);
1018- default:
1019- return S_dev_uknIntType;
1020- }
1021-}
1022-
1023-/*
1024- * devEnableInterruptLevel()
1025- *
1026- * !! DEPRECATED !!
1027- */
1028-long devEnableInterruptLevel(
1029-epicsInterruptType intType,
1030-unsigned level)
1031-{
1032- long status;
1033-
1034- if (!devLibInitFlag) {
1035- status = devLibInit();
1036- if (status) {
1037- return status;
1038- }
1039- }
1040-
1041- switch(intType){
1042- case intVME:
1043- case intVXI:
1044- return (*pdevLibVirtualOS->pDevEnableInterruptLevelVME) (level);
1045- default:
1046- return S_dev_uknIntType;
1047- }
1048-}
1049-
1050-/*
1051- * devDisableInterruptLevel()
1052- *
1053- * !! DEPRECATED !!
1054- */
1055-long devDisableInterruptLevel (
1056-epicsInterruptType intType,
1057-unsigned level)
1058-{
1059- long status;
1060-
1061- if (!devLibInitFlag) {
1062- status = devLibInit();
1063- if (status) {
1064- return status;
1065- }
1066- }
1067-
1068- switch(intType){
1069- case intVME:
1070- case intVXI:
1071- return (*pdevLibVirtualOS->pDevDisableInterruptLevelVME) (level);
1072- default:
1073- return S_dev_uknIntType;
1074- }
1075-}
1076-
1077-/*
1078- * locationProbe
1079- *
1080- * !! DEPRECATED !!
1081- */
1082-long locationProbe (epicsAddressType addrType, char *pLocation)
1083-{
1084- return devNoResponseProbe (addrType, (size_t) pLocation, sizeof(long));
1085-}
1086-
1087-/******************************************************************************
1088- *
1089- * The follwing may, or may not be present in the BSP for the CPU in use.
1090- *
1091- */
1092-/******************************************************************************
1093- *
1094- * Routines to use to allocate and free memory present in the A24 region.
1095- *
1096- ******************************************************************************/
1097-
1098-int devLibA24Debug = 0; /* Debugging flag */
1099-
1100-void *devLibA24Calloc(size_t size)
1101-{
1102- void *ret;
1103-
1104- ret = devLibA24Malloc(size);
1105-
1106- if (ret == NULL)
1107- return (NULL);
1108-
1109- memset(ret, 0x00, size);
1110- return(ret);
1111-}
1112-
1113-void *devLibA24Malloc(size_t size)
1114-{
1115- void *ret;
1116-
1117- if (devLibA24Debug)
1118- epicsPrintf ("devLibA24Malloc(%u) entered\n", (unsigned int)size);
1119-
1120- ret = pdevLibVirtualOS->pDevA24Malloc(size);
1121- return(ret);
1122-}
1123-
1124-void devLibA24Free(void *pBlock)
1125-{
1126- if (devLibA24Debug)
1127- epicsPrintf("devLibA24Free(%p) entered\n", pBlock);
1128-
1129- pdevLibVirtualOS->pDevA24Free(pBlock);
1130-}
1131
1132=== added file 'src/libCom/osi/devLib.h'
1133--- src/libCom/osi/devLib.h 1970-01-01 00:00:00 +0000
1134+++ src/libCom/osi/devLib.h 2010-05-28 11:06:32 +0000
1135@@ -0,0 +1,107 @@
1136+/*************************************************************************\
1137+* Copyright (c) 2010 Brookhaven Science Associates, as Operator of
1138+* Brookhaven National Laboratory.
1139+* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
1140+* National Laboratory.
1141+* Copyright (c) 2002 The Regents of the University of California, as
1142+* Operator of Los Alamos National Laboratory.
1143+* EPICS BASE is distributed subject to a Software License Agreement found
1144+* in file LICENSE that is included with this distribution.
1145+\*************************************************************************/
1146+/* devLib.h */
1147+/* $Id$ */
1148+
1149+/*
1150+ * Original Author: Marty Kraimer
1151+ * Author: Jeff Hill
1152+ * Date: 03-10-93
1153+ */
1154+#ifndef EPICSDEVLIB_H
1155+#define EPICSDEVLIB_H
1156+
1157+/*
1158+ * Support macros
1159+ */
1160+
1161+/*
1162+ * Normalize a digital value and convert it to type TYPE
1163+ *
1164+ * Ex:
1165+ * float f;
1166+ * int d;
1167+ * f = devNormalizeDigital(d,12)
1168+ *
1169+ */
1170+#define devCreateMask(NBITS) ((1<<(NBITS))-1)
1171+#define devDigToNml(DIGITAL,NBITS) \
1172+ (((double)(DIGITAL))/devCreateMask(NBITS))
1173+#define devNmlToDig(NORMAL,NBITS) \
1174+ (((long)(NORMAL)) * devCreateMask(NBITS))
1175+
1176+/*
1177+ *
1178+ * Alignment mask
1179+ * (for use when testing to see if the proper number of least
1180+ * significant bits are zero)
1181+ *
1182+ */
1183+#define devCreateAlignmentMask(CTYPE)\
1184+(sizeof(CTYPE)>sizeof(double)?sizeof(double)-1:sizeof(CTYPE)-1)
1185+
1186+/*
1187+ * pointer aligned test
1188+ * (returns true if the pointer is on the worst case alignemnt
1189+ * boundary for its type)
1190+ */
1191+#define devPtrAlignTest(PTR) (!(devCreateAlignmentMask(*PTR)&(long)(PTR)))
1192+
1193+/*
1194+ * error codes (and messages) associated with devLib.c
1195+ */
1196+#define S_dev_success 0
1197+#define S_dev_vectorInUse (M_devLib| 1) /*interrupt vector in use*/
1198+#define S_dev_vecInstlFail (M_devLib| 2) /*interrupt vector install failed*/
1199+#define S_dev_uknIntType (M_devLib| 3) /*Unrecognized interrupt type*/
1200+#define S_dev_vectorNotInUse (M_devLib| 4) /*Interrupt vector not in use by caller*/
1201+#define S_dev_badA16 (M_devLib| 5) /*Invalid VME A16 address*/
1202+#define S_dev_badA24 (M_devLib| 6) /*Invalid VME A24 address*/
1203+#define S_dev_badA32 (M_devLib| 7) /*Invalid VME A32 address*/
1204+#define S_dev_uknAddrType (M_devLib| 8) /*Unrecognized address space type*/
1205+#define S_dev_addressOverlap (M_devLib| 9) /*Specified device address overlaps another device*/
1206+#define S_dev_identifyOverlap (M_devLib| 10) /*This device already owns the address range*/
1207+#define S_dev_addrMapFail (M_devLib| 11) /*unable to map address*/
1208+#define S_dev_intDisconnect (M_devLib| 12) /*Interrupt at vector disconnected from an EPICS device*/
1209+#define S_dev_internal (M_devLib| 13) /*Internal failure*/
1210+#define S_dev_intEnFail (M_devLib| 14) /*unable to enable interrupt level*/
1211+#define S_dev_intDissFail (M_devLib| 15) /*unable to disable interrupt level*/
1212+#define S_dev_noMemory (M_devLib| 16) /*Memory allocation failed*/
1213+#define S_dev_addressNotFound (M_devLib| 17) /*Specified device address unregistered*/
1214+#define S_dev_noDevice (M_devLib| 18) /*No device at specified address*/
1215+#define S_dev_wrongDevice (M_devLib| 19) /*Wrong device type found at specified address*/
1216+#define S_dev_badSignalNumber (M_devLib| 20) /*Signal number (offset) to large*/
1217+#define S_dev_badSignalCount (M_devLib| 21) /*Signal count to large*/
1218+#define S_dev_badRequest (M_devLib| 22) /*Device does not support requested operation*/
1219+#define S_dev_highValue (M_devLib| 23) /*Parameter to high*/
1220+#define S_dev_lowValue (M_devLib| 24) /*Parameter to low*/
1221+#define S_dev_multDevice (M_devLib| 25) /*Specified address is ambiguous (more than one device responds)*/
1222+#define S_dev_badSelfTest (M_devLib| 26) /*Device self test failed*/
1223+#define S_dev_badInit (M_devLib| 27) /*Device failed during initialization*/
1224+#define S_dev_hdwLimit (M_devLib| 28) /*Input exceeds Hardware Limit*/
1225+#define S_dev_deviceDoesNotFit (M_devLib| 29) /*Unable to locate address space for device*/
1226+#define S_dev_deviceTMO (M_devLib| 30) /*device timed out*/
1227+#define S_dev_badFunction (M_devLib| 31) /*bad function pointer*/
1228+#define S_dev_badVector (M_devLib| 32) /*bad interrupt vector*/
1229+#define S_dev_badArgument (M_devLib| 33) /*bad function argument*/
1230+#define S_dev_badISA (M_devLib| 34) /*Invalid ISA address*/
1231+#define S_dev_badCRCSR (M_devLib| 35) /*Invalid VME CR/CSR address*/
1232+#define S_dev_vxWorksIntEnFail S_dev_intEnFail
1233+
1234+
1235+#endif /* EPICSDEVLIB_H */
1236+
1237+/*
1238+ * Retain compatibility by including VME by default
1239+ */
1240+#ifndef NO_DEVLIB_COMPAT
1241+# include "devLibVME.h"
1242+#endif
1243
1244=== removed file 'src/libCom/osi/devLib.h'
1245--- src/libCom/osi/devLib.h 2009-07-09 15:27:43 +0000
1246+++ src/libCom/osi/devLib.h 1970-01-01 00:00:00 +0000
1247@@ -1,444 +0,0 @@
1248-/*************************************************************************\
1249-* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
1250-* National Laboratory.
1251-* Copyright (c) 2002 The Regents of the University of California, as
1252-* Operator of Los Alamos National Laboratory.
1253-* EPICS BASE is distributed subject to a Software License Agreement found
1254-* in file LICENSE that is included with this distribution.
1255-\*************************************************************************/
1256-/* devLib.h */
1257-/* $Id$ */
1258-
1259-/*
1260- * Original Author: Marty Kraimer
1261- * Author: Jeff Hill
1262- * Date: 03-10-93
1263- */
1264-
1265-#ifndef INCdevLibh
1266-#define INCdevLibh 1
1267-
1268-#include "dbDefs.h"
1269-#include "osdVME.h"
1270-#include "errMdef.h"
1271-#include "shareLib.h"
1272-
1273-#ifdef __cplusplus
1274-extern "C" {
1275-#endif
1276-
1277-/*
1278- * epdevAddressType & EPICStovxWorksAddrType
1279- * devLib.c must change in unison
1280- */
1281-typedef enum {
1282- atVMEA16,
1283- atVMEA24,
1284- atVMEA32,
1285- atISA, /* memory mapped ISA access (until now only on PC) */
1286- atVMECSR, /* VME-64 CR/CSR address space */
1287- atLast /* atLast must be the last enum in this list */
1288- } epicsAddressType;
1289-
1290-/*
1291- * pointer to an array of strings for each of
1292- * the above address types
1293- */
1294-extern const char *epicsAddressTypeName[];
1295-
1296-epicsShareFunc long devAddressMap(void); /* print an address map */
1297-
1298-/*
1299- * devBusToLocalAddr()
1300- *
1301- * OSI routine to translate bus addresses their local CPU address mapping
1302- */
1303-epicsShareFunc long devBusToLocalAddr (
1304- epicsAddressType addrType,
1305- size_t busAddr,
1306- volatile void **ppLocalAddr);
1307-/*
1308- * devReadProbe()
1309- *
1310- * a bus error safe "wordSize" read at the specified address which returns
1311- * unsuccessful status if the device isnt present
1312- */
1313-epicsShareFunc long devReadProbe (
1314- unsigned wordSize, volatile const void *ptr, void *pValueRead);
1315-
1316-/*
1317- * devNoResponseProbe()
1318- *
1319- * Verifies that no devices respond at naturally aligned words
1320- * within the specified address range. Return success if no devices
1321- * respond. Returns an error if a device does respond or if
1322- * a physical address for a naturally aligned word cant be mapped.
1323- * Checks all naturally aligned word sizes between char and long for
1324- * the entire specified range of bytes.
1325- */
1326-epicsShareFunc long devNoResponseProbe(
1327- epicsAddressType addrType,
1328- size_t base,
1329- size_t size
1330-);
1331-
1332-/*
1333- * devWriteProbe
1334- *
1335- * a bus error safe "wordSize" write at the specified address which returns
1336- * unsuccessful status if the device isnt present
1337- */
1338-epicsShareFunc long devWriteProbe (
1339- unsigned wordSize, volatile void *ptr, const void *pValueWritten);
1340-
1341-epicsShareFunc long devRegisterAddress(
1342- const char *pOwnerName,
1343- epicsAddressType addrType,
1344- size_t logicalBaseAddress,
1345- size_t size, /* bytes */
1346- volatile void **pPhysicalAddress);
1347-
1348-epicsShareFunc long devUnregisterAddress(
1349- epicsAddressType addrType,
1350- size_t logicalBaseAddress,
1351- const char *pOwnerName);
1352-
1353-/*
1354- * allocate and register an unoccupied address block
1355- */
1356-epicsShareFunc long devAllocAddress(
1357- const char *pOwnerName,
1358- epicsAddressType addrType,
1359- size_t size,
1360- unsigned alignment, /*n ls bits zero in addr*/
1361- volatile void **pLocalAddress);
1362-
1363-/*
1364- * connect ISR to a VME interrupt vector
1365- */
1366-epicsShareFunc long devConnectInterruptVME(
1367- unsigned vectorNumber,
1368- void (*pFunction)(void *),
1369- void *parameter);
1370-
1371-/*
1372- * connect ISR to an ISA interrupt level
1373- * (not implemented)
1374- * (API should be reviewed)
1375- */
1376-epicsShareFunc long devConnectInterruptISA(
1377- unsigned interruptLevel,
1378- void (*pFunction)(void *),
1379- void *parameter);
1380-
1381-/*
1382- * connect ISR to a PCI interrupt
1383- * (not implemented)
1384- * (API should be reviewed)
1385- */
1386-epicsShareFunc long devConnectInterruptPCI(
1387- unsigned bus,
1388- unsigned device,
1389- unsigned function,
1390- void (*pFunction)(void *),
1391- void *parameter);
1392-
1393-/*
1394- * disconnect ISR from a VME interrupt vector
1395- *
1396- * The parameter pFunction should be set to the C function pointer that
1397- * was connected. It is used as a key to prevent a driver from inadvertently
1398- * removing an interrupt handler that it didn't install
1399- */
1400-epicsShareFunc long devDisconnectInterruptVME(
1401- unsigned vectorNumber,
1402- void (*pFunction)(void *));
1403-
1404-/*
1405- * disconnect ISR from an ISA interrupt level
1406- * (not implemented)
1407- * (API should be reviewed)
1408- *
1409- * The parameter pFunction should be set to the C function pointer that
1410- * was connected. It is used as a key to prevent a driver from inadvertently
1411- * removing an interrupt handler that it didn't install
1412- */
1413-epicsShareFunc long devDisconnectInterruptISA(
1414- unsigned interruptLevel,
1415- void (*pFunction)(void *));
1416-
1417-/*
1418- * disconnect ISR from a PCI interrupt
1419- * (not implemented)
1420- * (API should be reviewed)
1421- *
1422- * The parameter pFunction should be set to the C function pointer that
1423- * was connected. It is used as a key to prevent a driver from inadvertently
1424- * removing an interrupt handler that it didn't install
1425- */
1426-epicsShareFunc long devDisconnectInterruptPCI(
1427- unsigned bus,
1428- unsigned device,
1429- unsigned function,
1430- void (*pFunction)(void *));
1431-
1432-/*
1433- * determine if a VME interrupt vector is in use
1434- *
1435- * returns boolean
1436- */
1437-epicsShareFunc int devInterruptInUseVME (unsigned vectorNumber);
1438-
1439-/*
1440- * determine if an ISA interrupt level is in use
1441- * (not implemented)
1442- *
1443- * returns boolean
1444- */
1445-epicsShareFunc int devInterruptLevelInUseISA (unsigned interruptLevel);
1446-
1447-/*
1448- * determine if a PCI interrupt is in use
1449- * (not implemented)
1450- *
1451- * returns boolean
1452- */
1453-epicsShareFunc int devInterruptInUsePCI (unsigned bus, unsigned device,
1454- unsigned function);
1455-
1456-typedef enum {intVME, intVXI, intISA} epicsInterruptType;
1457-
1458-/*
1459- * enable VME interrupt level
1460- */
1461-epicsShareFunc long devEnableInterruptLevelVME (unsigned level);
1462-
1463-/*
1464- * enable ISA interrupt level
1465- */
1466-epicsShareFunc long devEnableInterruptLevelISA (unsigned level);
1467-
1468-/*
1469- * not implemented - API needs to be reviewed
1470- */
1471-epicsShareFunc long devEnableInterruptLevelPCI (unsigned level,
1472- unsigned bus, unsigned device, unsigned function);
1473-
1474-/*
1475- * disable VME interrupt level
1476- */
1477-epicsShareFunc long devDisableInterruptLevelVME (unsigned level);
1478-
1479-/*
1480- * disable ISA interrupt level
1481- */
1482-epicsShareFunc long devDisableInterruptLevelISA (unsigned level);
1483-
1484-/*
1485- * not implemented - API needs to be reviewed
1486- */
1487-epicsShareFunc long devDisableInterruptLevelPCI (unsigned level,
1488- unsigned bus, unsigned device, unsigned function);
1489-
1490-/*
1491- * Routines to allocate and free memory in the A24 memory region.
1492- *
1493- */
1494-epicsShareFunc void *devLibA24Malloc(size_t);
1495-epicsShareFunc void *devLibA24Calloc(size_t);
1496-epicsShareFunc void devLibA24Free(void *pBlock);
1497-
1498-/*
1499- * Normalize a digital value and convert it to type TYPE
1500- *
1501- * Ex:
1502- * float f;
1503- * int d;
1504- * f = devNormalizeDigital(d,12)
1505- *
1506- */
1507-#define devCreateMask(NBITS) ((1<<(NBITS))-1)
1508-#define devDigToNml(DIGITAL,NBITS) \
1509- (((double)(DIGITAL))/devCreateMask(NBITS))
1510-#define devNmlToDig(NORMAL,NBITS) \
1511- (((long)(NORMAL)) * devCreateMask(NBITS))
1512-
1513-/*
1514- *
1515- * Alignment mask
1516- * (for use when testing to see if the proper number of least
1517- * significant bits are zero)
1518- *
1519- */
1520-#define devCreateAlignmentMask(CTYPE)\
1521-(sizeof(CTYPE)>sizeof(double)?sizeof(double)-1:sizeof(CTYPE)-1)
1522-
1523-/*
1524- * pointer aligned test
1525- * (returns true if the pointer is on the worst case alignemnt
1526- * boundary for its type)
1527- */
1528-#define devPtrAlignTest(PTR) (!(devCreateAlignmentMask(*PTR)&(long)(PTR)))
1529-
1530-/*
1531- * virtual OS layer for devLib.c
1532- */
1533-typedef struct devLibVirtualOS {
1534- /*
1535- * maps logical address to physical address, but does not detect
1536- * two device drivers that are using the same address range
1537- */
1538- long (*pDevMapAddr) (epicsAddressType addrType, unsigned options,
1539- size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
1540-
1541- /*
1542- * a bus error safe "wordSize" read at the specified address which returns
1543- * unsuccessful status if the device isnt present
1544- */
1545- long (*pDevReadProbe) (unsigned wordSize, volatile const void *ptr, void *pValueRead);
1546-
1547- /*
1548- * a bus error safe "wordSize" write at the specified address which returns
1549- * unsuccessful status if the device isnt present
1550- */
1551- long (*pDevWriteProbe) (unsigned wordSize, volatile void *ptr, const void *pValueWritten);
1552-
1553- /*
1554- * connect ISR to a VME interrupt vector
1555- * (required for backwards compatibility)
1556- */
1557- long (*pDevConnectInterruptVME) (unsigned vectorNumber,
1558- void (*pFunction)(void *), void *parameter);
1559-
1560- /*
1561- * disconnect ISR from a VME interrupt vector
1562- * (required for backwards compatibility)
1563- */
1564- long (*pDevDisconnectInterruptVME) (unsigned vectorNumber,
1565- void (*pFunction)(void *));
1566-
1567- /*
1568- * enable VME interrupt level
1569- */
1570- long (*pDevEnableInterruptLevelVME) (unsigned level);
1571-
1572- /*
1573- * disable VME interrupt level
1574- */
1575- long (*pDevDisableInterruptLevelVME) (unsigned level);
1576- /* malloc/free A24 address space */
1577- void *(*pDevA24Malloc)(size_t nbytes);
1578- void (*pDevA24Free)(void *pBlock);
1579- long (*pDevInit)(void);
1580-}devLibVirtualOS;
1581-epicsShareExtern devLibVirtualOS *pdevLibVirtualOS;
1582-
1583-/*
1584- * error codes (and messages) associated with devLib.c
1585- */
1586-#define S_dev_success 0
1587-#define S_dev_vectorInUse (M_devLib| 1) /*interrupt vector in use*/
1588-#define S_dev_vecInstlFail (M_devLib| 2) /*interrupt vector install failed*/
1589-#define S_dev_uknIntType (M_devLib| 3) /*Unrecognized interrupt type*/
1590-#define S_dev_vectorNotInUse (M_devLib| 4) /*Interrupt vector not in use by caller*/
1591-#define S_dev_badA16 (M_devLib| 5) /*Invalid VME A16 address*/
1592-#define S_dev_badA24 (M_devLib| 6) /*Invalid VME A24 address*/
1593-#define S_dev_badA32 (M_devLib| 7) /*Invalid VME A32 address*/
1594-#define S_dev_uknAddrType (M_devLib| 8) /*Unrecognized address space type*/
1595-#define S_dev_addressOverlap (M_devLib| 9) /*Specified device address overlaps another device*/
1596-#define S_dev_identifyOverlap (M_devLib| 10) /*This device already owns the address range*/
1597-#define S_dev_addrMapFail (M_devLib| 11) /*unable to map address*/
1598-#define S_dev_intDisconnect (M_devLib| 12) /*Interrupt at vector disconnected from an EPICS device*/
1599-#define S_dev_internal (M_devLib| 13) /*Internal failure*/
1600-#define S_dev_intEnFail (M_devLib| 14) /*unable to enable interrupt level*/
1601-#define S_dev_intDissFail (M_devLib| 15) /*unable to disable interrupt level*/
1602-#define S_dev_noMemory (M_devLib| 16) /*Memory allocation failed*/
1603-#define S_dev_addressNotFound (M_devLib| 17) /*Specified device address unregistered*/
1604-#define S_dev_noDevice (M_devLib| 18) /*No device at specified address*/
1605-#define S_dev_wrongDevice (M_devLib| 19) /*Wrong device type found at specified address*/
1606-#define S_dev_badSignalNumber (M_devLib| 20) /*Signal number (offset) to large*/
1607-#define S_dev_badSignalCount (M_devLib| 21) /*Signal count to large*/
1608-#define S_dev_badRequest (M_devLib| 22) /*Device does not support requested operation*/
1609-#define S_dev_highValue (M_devLib| 23) /*Parameter to high*/
1610-#define S_dev_lowValue (M_devLib| 24) /*Parameter to low*/
1611-#define S_dev_multDevice (M_devLib| 25) /*Specified address is ambiguous (more than one device responds)*/
1612-#define S_dev_badSelfTest (M_devLib| 26) /*Device self test failed*/
1613-#define S_dev_badInit (M_devLib| 27) /*Device failed during initialization*/
1614-#define S_dev_hdwLimit (M_devLib| 28) /*Input exceeds Hardware Limit*/
1615-#define S_dev_deviceDoesNotFit (M_devLib| 29) /*Unable to locate address space for device*/
1616-#define S_dev_deviceTMO (M_devLib| 30) /*device timed out*/
1617-#define S_dev_badFunction (M_devLib| 31) /*bad function pointer*/
1618-#define S_dev_badVector (M_devLib| 32) /*bad interrupt vector*/
1619-#define S_dev_badArgument (M_devLib| 33) /*bad function argument*/
1620-#define S_dev_badISA (M_devLib| 34) /*Invalid ISA address*/
1621-#define S_dev_badCRCSR (M_devLib| 35) /*Invalid VME CR/CSR address*/
1622-#define S_dev_vxWorksIntEnFail S_dev_intEnFail
1623-
1624-/*
1625- * NOTE: this routine has been deprecated. It exists
1626- * for backwards compatibility purposes only.
1627- *
1628- * Please use one of devConnectInterruptVME, devConnectInterruptPCI,
1629- * devConnectInterruptISA etc. devConnectInterrupt will be removed
1630- * in a future release.
1631- */
1632-epicsShareFunc long devConnectInterrupt(
1633- epicsInterruptType intType,
1634- unsigned vectorNumber,
1635- void (*pFunction)(void *),
1636- void *parameter);
1637-
1638-/*
1639- * NOTE: this routine has been deprecated. It exists
1640- * for backwards compatibility purposes only.
1641- *
1642- * Please use one of devDisconnectInterruptVME, devDisconnectInterruptPCI,
1643- * devDisconnectInterruptISA etc. devDisconnectInterrupt will be removed
1644- * in a future release.
1645- */
1646-epicsShareFunc long devDisconnectInterrupt(
1647- epicsInterruptType intType,
1648- unsigned vectorNumber,
1649- void (*pFunction)(void *));
1650-
1651-/*
1652- * NOTE: this routine has been deprecated. It exists
1653- * for backwards compatibility purposes only.
1654- *
1655- * Please use one of devEnableInterruptLevelVME, devEnableInterruptLevelPCI,
1656- * devEnableInterruptLevelISA etc. devEnableInterruptLevel will be removed
1657- * in a future release.
1658- */
1659-epicsShareFunc long devEnableInterruptLevel(
1660- epicsInterruptType intType, unsigned level);
1661-
1662-/*
1663- * NOTE: this routine has been deprecated. It exists
1664- * for backwards compatibility purposes only.
1665- *
1666- * Please use one of devDisableInterruptLevelVME, devDisableInterruptLevelISA,
1667- * devDisableInterruptLevelPCI etc. devDisableInterruptLevel will be removed
1668- * in a future release.
1669- */
1670-epicsShareFunc long devDisableInterruptLevel (
1671- epicsInterruptType intType, unsigned level);
1672-
1673-/*
1674- * NOTE: this routine has been deprecated. It exists
1675- * for backwards compatibility purposes only.
1676- *
1677- * Please use devNoResponseProbe(). locationProbe() will be removed
1678- * in a future release.
1679- */
1680-epicsShareFunc long locationProbe (epicsAddressType addrType, char *pLocation);
1681-
1682-/*
1683- * Some vxWorks convenience routines
1684- */
1685-void bcopyLongs(char *source, char *destination, int nlongs);
1686-
1687-#ifdef __cplusplus
1688-}
1689-#endif
1690-
1691-#endif /* INCdevLibh.h*/
1692
1693=== added file 'src/libCom/osi/devLibVME.c'
1694--- src/libCom/osi/devLibVME.c 1970-01-01 00:00:00 +0000
1695+++ src/libCom/osi/devLibVME.c 2010-05-28 11:06:32 +0000
1696@@ -0,0 +1,1159 @@
1697+/*************************************************************************\
1698+* Copyright (c) 2010 Brookhaven Science Associates, as Operator of
1699+* Brookhaven National Laboratory.
1700+* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
1701+* National Laboratory.
1702+* Copyright (c) 2002 The Regents of the University of California, as
1703+* Operator of Los Alamos National Laboratory.
1704+* EPICS BASE is distributed subject to a Software License Agreement found
1705+* in file LICENSE that is included with this distribution.
1706+\*************************************************************************/
1707+/* devLib.c - support for allocation of common device resources */
1708+/* $Id$ */
1709+
1710+/*
1711+ * Original Author: Marty Kraimer
1712+ * Author: Jeff Hill
1713+ * Date: 03-10-93
1714+ *
1715+ * NOTES:
1716+ * .01 06-14-93 joh needs devAllocInterruptVector() routine
1717+ */
1718+
1719+static const char sccsID[] = "@(#) $Id$";
1720+
1721+#include <string.h>
1722+#include <stdio.h>
1723+#include <stdlib.h>
1724+
1725+#define epicsExportSharedSymbols
1726+#include "dbDefs.h"
1727+#include "epicsMutex.h"
1728+#include "errlog.h"
1729+#include "ellLib.h"
1730+
1731+#define NO_DEVLIB_COMPAT
1732+#include "devLibVME.h"
1733+#include "devLibVMEImpl.h"
1734+
1735+static ELLLIST addrAlloc[atLast];
1736+static ELLLIST addrFree[atLast];
1737+
1738+static size_t addrLast[atLast] = {
1739+ 0xffff,
1740+ 0xffffff,
1741+ 0xffffffff,
1742+ 0xffffff,
1743+ 0xffffff,
1744+ };
1745+
1746+static unsigned addrHexDig[atLast] = {
1747+ 4,
1748+ 6,
1749+ 8,
1750+ 6,
1751+ 6
1752+ };
1753+
1754+static long addrFail[atLast] = {
1755+ S_dev_badA16,
1756+ S_dev_badA24,
1757+ S_dev_badA32,
1758+ S_dev_badISA,
1759+ S_dev_badCRCSR
1760+ };
1761+
1762+static epicsMutexId addrListLock;
1763+static char devLibInitFlag;
1764+
1765+const char *epicsAddressTypeName[]
1766+ = {
1767+ "VME A16",
1768+ "VME A24",
1769+ "VME A32",
1770+ "ISA",
1771+ "VME CR/CSR"
1772+ };
1773+
1774+typedef struct{
1775+ ELLNODE node;
1776+ const char *pOwnerName;
1777+ volatile void *pPhysical;
1778+ /*
1779+ * first, last is used here instead of base, size
1780+ * so that we can store a block that is the maximum size
1781+ * available in type size_t
1782+ */
1783+ size_t begin;
1784+ size_t end;
1785+}rangeItem;
1786+
1787+/*
1788+ * These routines are not exported
1789+ */
1790+
1791+static long devLibInit(void);
1792+
1793+static long addrVerify(
1794+ epicsAddressType addrType,
1795+ size_t base,
1796+ size_t size);
1797+
1798+static long blockFind (
1799+ epicsAddressType addrType,
1800+ const rangeItem *pRange,
1801+ /* size needed */
1802+ size_t requestSize,
1803+ /* n ls bits zero in base addr */
1804+ unsigned alignment,
1805+ /* base address found */
1806+ size_t *pFirst);
1807+
1808+static void report_conflict(
1809+ epicsAddressType addrType,
1810+ size_t base,
1811+ size_t size,
1812+ const char *pOwnerName);
1813+
1814+static void report_conflict_device(
1815+ epicsAddressType addrType,
1816+ const rangeItem *pRange);
1817+
1818+static void devInsertAddress(
1819+ ELLLIST *pRangeList,
1820+ rangeItem *pNewRange);
1821+
1822+static long devListAddressMap(
1823+ ELLLIST *pRangeList);
1824+
1825+static long devCombineAdjacentBlocks(
1826+ ELLLIST *pRangeList,
1827+ rangeItem *pRange);
1828+
1829+static long devInstallAddr(
1830+ rangeItem *pRange, /* item on the free list to be split */
1831+ const char *pOwnerName,
1832+ epicsAddressType addrType,
1833+ size_t base,
1834+ size_t size,
1835+ volatile void **ppPhysicalAddress);
1836+
1837+#define SUCCESS 0
1838+
1839+/*
1840+ * devBusToLocalAddr()
1841+ */
1842+long devBusToLocalAddr(
1843+ epicsAddressType addrType,
1844+ size_t busAddr,
1845+ volatile void **ppLocalAddress)
1846+{
1847+ long status;
1848+ volatile void *localAddress;
1849+
1850+ /*
1851+ * Make sure that devLib has been intialized
1852+ */
1853+ if (!devLibInitFlag) {
1854+ status = devLibInit();
1855+ if(status){
1856+ return status;
1857+ }
1858+ }
1859+
1860+ /*
1861+ * Make sure we have a valid bus address
1862+ */
1863+ status = addrVerify (addrType, busAddr, 4);
1864+ if (status) {
1865+ return status;
1866+ }
1867+
1868+ /*
1869+ * Call the virtual os routine to map the bus address to a CPU address
1870+ */
1871+ status = (*pdevLibVME->pDevMapAddr) (addrType, 0, busAddr, 4, &localAddress);
1872+ if (status) {
1873+ errPrintf (status, __FILE__, __LINE__, "%s bus address =0X%X\n",
1874+ epicsAddressTypeName[addrType], (unsigned int)busAddr);
1875+ return status;
1876+ }
1877+
1878+ /*
1879+ * Return the local CPU address if the pointer is supplied
1880+ */
1881+ if (ppLocalAddress) {
1882+ *ppLocalAddress = localAddress;
1883+ }
1884+
1885+ return SUCCESS;
1886+
1887+}/*end devBusToLocalAddr()*/
1888+
1889+
1890+/*
1891+ * devRegisterAddress()
1892+ */
1893+long devRegisterAddress(
1894+ const char *pOwnerName,
1895+ epicsAddressType addrType,
1896+ size_t base,
1897+ size_t size,
1898+ volatile void **ppPhysicalAddress)
1899+{
1900+ rangeItem *pRange;
1901+ long s;
1902+
1903+ if (!devLibInitFlag) {
1904+ s = devLibInit();
1905+ if(s){
1906+ return s;
1907+ }
1908+ }
1909+
1910+ s = addrVerify (addrType, base, size);
1911+ if (s) {
1912+ return s;
1913+ }
1914+
1915+ if (size == 0) {
1916+ return S_dev_lowValue;
1917+ }
1918+
1919+#ifdef DEBUG
1920+ printf ("Req Addr 0X%X Size 0X%X\n", base, size);
1921+#endif
1922+
1923+ epicsMutexMustLock(addrListLock);
1924+ pRange = (rangeItem *) ellFirst(&addrFree[addrType]);
1925+ while (TRUE) {
1926+ if (pRange->begin > base) {
1927+ pRange = NULL;
1928+# ifdef DEBUG
1929+ printf ("Unable to locate a free block\n");
1930+ devListAddressMap (&addrFree[addrType]);
1931+# endif
1932+ break;
1933+ }
1934+ else if (base + (size - 1) <= pRange->end) {
1935+# ifdef DEBUG
1936+ printf ("Found free block Begin 0X%X End 0X%X\n",
1937+ pRange->begin, pRange->end);
1938+# endif
1939+ break;
1940+ }
1941+
1942+ pRange = (rangeItem *) ellNext (&pRange->node);
1943+ }
1944+ epicsMutexUnlock(addrListLock);
1945+
1946+ if (pRange==NULL) {
1947+ report_conflict (addrType, base, size, pOwnerName);
1948+ return S_dev_addressOverlap;
1949+ }
1950+
1951+ s = devInstallAddr(
1952+ pRange, /* item on the free list to be split */
1953+ pOwnerName,
1954+ addrType,
1955+ base,
1956+ size,
1957+ ppPhysicalAddress);
1958+
1959+ return s;
1960+}
1961+
1962+/*
1963+ * devReadProbe()
1964+ *
1965+ * a bus error safe "wordSize" read at the specified address which returns
1966+ * unsuccessful status if the device isnt present
1967+ */
1968+long devReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue)
1969+{
1970+ long status;
1971+
1972+ if (!devLibInitFlag) {
1973+ status = devLibInit();
1974+ if (status) {
1975+ return status;
1976+ }
1977+ }
1978+
1979+ return (*pdevLibVME->pDevReadProbe) (wordSize, ptr, pValue);
1980+}
1981+
1982+/*
1983+ * devWriteProbe
1984+ *
1985+ * a bus error safe "wordSize" write at the specified address which returns
1986+ * unsuccessful status if the device isnt present
1987+ */
1988+long devWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue)
1989+{
1990+ long status;
1991+
1992+ if (!devLibInitFlag) {
1993+ status = devLibInit();
1994+ if (status) {
1995+ return status;
1996+ }
1997+ }
1998+
1999+ return (*pdevLibVME->pDevWriteProbe) (wordSize, ptr, pValue);
2000+}
2001+
2002+/*
2003+ * devInstallAddr()
2004+ */
2005+static long devInstallAddr (
2006+ rangeItem *pRange, /* item on the free list to be split */
2007+ const char *pOwnerName,
2008+ epicsAddressType addrType,
2009+ size_t base,
2010+ size_t size,
2011+ volatile void **ppPhysicalAddress)
2012+{
2013+ volatile void *pPhysicalAddress;
2014+ rangeItem *pNewRange;
2015+ size_t reqEnd = base + (size-1);
2016+ long status;
2017+
2018+ /*
2019+ * does it start below the specified block
2020+ */
2021+ if (base < pRange->begin) {
2022+ return S_dev_badArgument;
2023+ }
2024+
2025+ /*
2026+ * does it end above the specified block
2027+ */
2028+ if (reqEnd > pRange->end) {
2029+ return S_dev_badArgument;
2030+ }
2031+
2032+ /*
2033+ * always map through the virtual os in case the memory
2034+ * management is set up there
2035+ */
2036+ status = (*pdevLibVME->pDevMapAddr) (addrType, 0, base,
2037+ size, &pPhysicalAddress);
2038+ if (status) {
2039+ errPrintf (status, __FILE__, __LINE__, "%s base=0X%X size = 0X%X",
2040+ epicsAddressTypeName[addrType], (unsigned int)base, (unsigned int)size);
2041+ return status;
2042+ }
2043+
2044+ /*
2045+ * set the callers variable if the pointer is supplied
2046+ */
2047+ if (ppPhysicalAddress) {
2048+ *ppPhysicalAddress = pPhysicalAddress;
2049+ }
2050+
2051+ /*
2052+ * does it start at the beginning of the block
2053+ */
2054+ if (pRange->begin == base) {
2055+ if (pRange->end == reqEnd) {
2056+ epicsMutexMustLock(addrListLock);
2057+ ellDelete(&addrFree[addrType], &pRange->node);
2058+ epicsMutexUnlock(addrListLock);
2059+ free ((void *)pRange);
2060+ }
2061+ else {
2062+ pRange->begin = base + size;
2063+ }
2064+ }
2065+ /*
2066+ * does it end at the end of the block
2067+ */
2068+ else if (pRange->end == reqEnd) {
2069+ pRange->end = base-1;
2070+ }
2071+ /*
2072+ * otherwise split the item on the free list
2073+ */
2074+ else {
2075+
2076+ pNewRange = (rangeItem *) calloc (1, sizeof(*pRange));
2077+ if(!pNewRange){
2078+ return S_dev_noMemory;
2079+ }
2080+
2081+ pNewRange->begin = base + size;
2082+ pNewRange->end = pRange->end;
2083+ pNewRange->pOwnerName = "<fragmented block>";
2084+ pNewRange->pPhysical = NULL;
2085+ pRange->end = base - 1;
2086+
2087+ /*
2088+ * add the node after the old item on the free list
2089+ * (blocks end up ordered by address)
2090+ */
2091+ epicsMutexMustLock(addrListLock);
2092+ ellInsert(&addrFree[addrType], &pRange->node, &pNewRange->node);
2093+ epicsMutexUnlock(addrListLock);
2094+ }
2095+
2096+ /*
2097+ * allocate a new address range entry and add it to
2098+ * the list
2099+ */
2100+ pNewRange = (rangeItem *)calloc (1, sizeof(*pRange));
2101+ if (!pNewRange) {
2102+ return S_dev_noMemory;
2103+ }
2104+
2105+ pNewRange->begin = base;
2106+ pNewRange->end = reqEnd;
2107+ pNewRange->pOwnerName = pOwnerName;
2108+ pNewRange->pPhysical = pPhysicalAddress;
2109+
2110+ devInsertAddress (&addrAlloc[addrType], pNewRange);
2111+
2112+ return SUCCESS;
2113+}
2114+
2115+/*
2116+ * report_conflict()
2117+ */
2118+static void report_conflict (
2119+ epicsAddressType addrType,
2120+ size_t base,
2121+ size_t size,
2122+ const char *pOwnerName
2123+)
2124+{
2125+ const rangeItem *pRange;
2126+
2127+ errPrintf (
2128+ S_dev_addressOverlap,
2129+ __FILE__,
2130+ __LINE__,
2131+ "%10s 0X%08X - OX%08X Requested by %s",
2132+ epicsAddressTypeName[addrType],
2133+ (unsigned int)base,
2134+ (unsigned int)(base+size-1),
2135+ pOwnerName);
2136+
2137+ pRange = (rangeItem *) ellFirst(&addrAlloc[addrType]);
2138+ while (pRange) {
2139+
2140+ if (pRange->begin <= base + (size-1) && pRange->end >= base) {
2141+ report_conflict_device (addrType, pRange);
2142+ }
2143+
2144+ pRange = (rangeItem *) pRange->node.next;
2145+ }
2146+}
2147+
2148+/*
2149+ * report_conflict_device()
2150+ */
2151+static void report_conflict_device(epicsAddressType addrType, const rangeItem *pRange)
2152+{
2153+ errPrintf (
2154+ S_dev_identifyOverlap,
2155+ __FILE__,
2156+ __LINE__,
2157+ "%10s 0X%08X - 0X%08X Owned by %s",
2158+ epicsAddressTypeName[addrType],
2159+ (unsigned int)pRange->begin,
2160+ (unsigned int)pRange->end,
2161+ pRange->pOwnerName);
2162+}
2163+
2164+/*
2165+ * devUnregisterAddress()
2166+ */
2167+long devUnregisterAddress(
2168+ epicsAddressType addrType,
2169+ size_t baseAddress,
2170+ const char *pOwnerName)
2171+{
2172+ rangeItem *pRange;
2173+ int s;
2174+
2175+ if (!devLibInitFlag) {
2176+ s = devLibInit();
2177+ if(s) {
2178+ return s;
2179+ }
2180+ }
2181+
2182+ s = addrVerify (addrType, baseAddress, 1);
2183+ if (s != SUCCESS) {
2184+ return s;
2185+ }
2186+
2187+ epicsMutexMustLock(addrListLock);
2188+ pRange = (rangeItem *) ellFirst(&addrAlloc[addrType]);
2189+ while (pRange) {
2190+ if (pRange->begin == baseAddress) {
2191+ break;
2192+ }
2193+ if (pRange->begin > baseAddress) {
2194+ pRange = NULL;
2195+ break;
2196+ }
2197+ pRange = (rangeItem *) ellNext(&pRange->node);
2198+ }
2199+ epicsMutexUnlock(addrListLock);
2200+
2201+ if (!pRange) {
2202+ return S_dev_addressNotFound;
2203+ }
2204+
2205+ if (strcmp(pOwnerName,pRange->pOwnerName)) {
2206+ s = S_dev_addressOverlap;
2207+ errPrintf (
2208+ s,
2209+ __FILE__,
2210+ __LINE__,
2211+ "unregister address for %s at 0X%X failed because %s owns it",
2212+ pOwnerName,
2213+ (unsigned int)baseAddress,
2214+ pRange->pOwnerName);
2215+ return s;
2216+ }
2217+
2218+ epicsMutexMustLock(addrListLock);
2219+ ellDelete (&addrAlloc[addrType], &pRange->node);
2220+ epicsMutexUnlock(addrListLock);
2221+
2222+ pRange->pOwnerName = "<released fragment>";
2223+ devInsertAddress (&addrFree[addrType], pRange);
2224+ s = devCombineAdjacentBlocks (&addrFree[addrType], pRange);
2225+ if(s){
2226+ errMessage (s, "devCombineAdjacentBlocks error");
2227+ return s;
2228+ }
2229+
2230+ return SUCCESS;
2231+}
2232+
2233+/*
2234+ * devCombineAdjacentBlocks()
2235+ */
2236+static long devCombineAdjacentBlocks(
2237+ ELLLIST *pRangeList,
2238+ rangeItem *pRange)
2239+{
2240+ rangeItem *pBefore;
2241+ rangeItem *pAfter;
2242+
2243+ pBefore = (rangeItem *) ellPrevious (&pRange->node);
2244+ pAfter = (rangeItem *) ellNext (&pRange->node);
2245+
2246+ /*
2247+ * combine adjacent blocks
2248+ */
2249+ if (pBefore) {
2250+ if (pBefore->end == pRange->begin-1) {
2251+ epicsMutexMustLock(addrListLock);
2252+ pRange->begin = pBefore->begin;
2253+ ellDelete (pRangeList, &pBefore->node);
2254+ epicsMutexUnlock(addrListLock);
2255+ free ((void *)pBefore);
2256+ }
2257+ }
2258+
2259+ if (pAfter) {
2260+ if (pAfter->begin == pRange->end+1) {
2261+ epicsMutexMustLock(addrListLock);
2262+ pRange->end = pAfter->end;
2263+ ellDelete (pRangeList, &pAfter->node);
2264+ epicsMutexUnlock(addrListLock);
2265+ free((void *)pAfter);
2266+ }
2267+ }
2268+
2269+ return SUCCESS;
2270+}
2271+
2272+/*
2273+ * devInsertAddress()
2274+ */
2275+static void devInsertAddress(
2276+ELLLIST *pRangeList,
2277+rangeItem *pNewRange)
2278+{
2279+ rangeItem *pBefore;
2280+ rangeItem *pAfter;
2281+
2282+ epicsMutexMustLock(addrListLock);
2283+ pAfter = (rangeItem *) ellFirst (pRangeList);
2284+ while (pAfter) {
2285+ if (pNewRange->end < pAfter->begin) {
2286+ break;
2287+ }
2288+ pAfter = (rangeItem *) ellNext (&pAfter->node);
2289+ }
2290+
2291+ if (pAfter) {
2292+ pBefore = (rangeItem *) ellPrevious (&pAfter->node);
2293+ ellInsert (pRangeList, &pBefore->node, &pNewRange->node);
2294+ }
2295+ else {
2296+ ellAdd (pRangeList, &pNewRange->node);
2297+ }
2298+ epicsMutexUnlock(addrListLock);
2299+}
2300+
2301+/*
2302+ * devAllocAddress()
2303+ */
2304+long devAllocAddress(
2305+ const char *pOwnerName,
2306+ epicsAddressType addrType,
2307+ size_t size,
2308+ unsigned alignment, /* n ls bits zero in base addr*/
2309+ volatile void ** pLocalAddress )
2310+{
2311+ int s;
2312+ rangeItem *pRange;
2313+ size_t base = 0;
2314+
2315+ if (!devLibInitFlag) {
2316+ s = devLibInit();
2317+ if(s){
2318+ return s;
2319+ }
2320+ }
2321+
2322+ s = addrVerify (addrType, 0, size);
2323+ if(s){
2324+ return s;
2325+ }
2326+
2327+ if (size == 0) {
2328+ return S_dev_lowValue;
2329+ }
2330+
2331+ epicsMutexMustLock(addrListLock);
2332+ pRange = (rangeItem *) ellFirst (&addrFree[addrType]);
2333+ while (pRange) {
2334+ if ((pRange->end - pRange->begin) + 1 >= size){
2335+ s = blockFind (
2336+ addrType,
2337+ pRange,
2338+ size,
2339+ alignment,
2340+ &base);
2341+ if (s==SUCCESS) {
2342+ break;
2343+ }
2344+ }
2345+ pRange = (rangeItem *) pRange->node.next;
2346+ }
2347+ epicsMutexUnlock(addrListLock);
2348+
2349+ if(!pRange){
2350+ s = S_dev_deviceDoesNotFit;
2351+ errMessage(s, epicsAddressTypeName[addrType]);
2352+ return s;
2353+ }
2354+
2355+ s = devInstallAddr (pRange, pOwnerName, addrType, base,
2356+ size, pLocalAddress);
2357+
2358+ return s;
2359+}
2360+
2361+/*
2362+ * addrVerify()
2363+ *
2364+ * care has been taken here not to overflow type size_t
2365+ */
2366+static long addrVerify(epicsAddressType addrType, size_t base, size_t size)
2367+{
2368+ if (addrType>=atLast) {
2369+ return S_dev_uknAddrType;
2370+ }
2371+
2372+ if (size == 0) {
2373+ return addrFail[addrType];
2374+ }
2375+
2376+ if (size-1 > addrLast[addrType]) {
2377+ return addrFail[addrType];
2378+ }
2379+
2380+ if (base > addrLast[addrType]) {
2381+ return addrFail[addrType];
2382+ }
2383+
2384+ if (size - 1 > addrLast[addrType] - base) {
2385+ return addrFail[addrType];
2386+ }
2387+
2388+ return SUCCESS;
2389+}
2390+
2391+/*
2392+ * devLibInit()
2393+ */
2394+static long devLibInit (void)
2395+{
2396+ rangeItem *pRange;
2397+ int i;
2398+
2399+
2400+ if(devLibInitFlag) return(SUCCESS);
2401+ if(!pdevLibVME) {
2402+ epicsPrintf ("pdevLibVME is NULL\n");
2403+ return S_dev_internal;
2404+ }
2405+
2406+ if (NELEMENTS(addrAlloc) != NELEMENTS(addrFree)) {
2407+ return S_dev_internal;
2408+ }
2409+
2410+ addrListLock = epicsMutexMustCreate();
2411+
2412+ epicsMutexMustLock(addrListLock);
2413+ for (i=0; i<NELEMENTS(addrAlloc); i++) {
2414+ ellInit (&addrAlloc[i]);
2415+ ellInit (&addrFree[i]);
2416+ }
2417+
2418+ for (i=0; i<NELEMENTS(addrAlloc); i++) {
2419+ pRange = (rangeItem *) malloc (sizeof(*pRange));
2420+ if (!pRange) {
2421+ return S_dev_noMemory;
2422+ }
2423+ pRange->pOwnerName = "<Vacant>";
2424+ pRange->pPhysical = NULL;
2425+ pRange->begin = 0;
2426+ pRange->end = addrLast[i];
2427+ ellAdd (&addrFree[i], &pRange->node);
2428+ }
2429+ epicsMutexUnlock(addrListLock);
2430+ devLibInitFlag = TRUE;
2431+ return pdevLibVME->pDevInit();
2432+}
2433+
2434+/*
2435+ * devAddressMap()
2436+ */
2437+long devAddressMap(void)
2438+{
2439+ return devListAddressMap(addrAlloc);
2440+}
2441+
2442+/*
2443+ * devListAddressMap()
2444+ */
2445+static long devListAddressMap(ELLLIST *pRangeList)
2446+{
2447+ rangeItem *pri;
2448+ int i;
2449+ long s;
2450+
2451+ if (!devLibInitFlag) {
2452+ s = devLibInit ();
2453+ if (s) {
2454+ return s;
2455+ }
2456+ }
2457+
2458+ epicsMutexMustLock(addrListLock);
2459+ for (i=0; i<NELEMENTS(addrAlloc); i++) {
2460+ pri = (rangeItem *) ellFirst(&pRangeList[i]);
2461+ if (pri) {
2462+ printf ("%s Address Map\n", epicsAddressTypeName[i]);
2463+ }
2464+ while (pri) {
2465+ printf ("\t0X%0*lX - 0X%0*lX physical base %p %s\n",
2466+ addrHexDig[i],
2467+ (unsigned long) pri->begin,
2468+ addrHexDig[i],
2469+ (unsigned long) pri->end,
2470+ pri->pPhysical,
2471+ pri->pOwnerName);
2472+ pri = (rangeItem *) ellNext (&pri->node);
2473+ }
2474+ }
2475+ epicsMutexUnlock(addrListLock);
2476+
2477+ return SUCCESS;
2478+}
2479+
2480+
2481+/*
2482+ *
2483+ * blockFind()
2484+ *
2485+ * Find unoccupied block in a large block
2486+ *
2487+ */
2488+static long blockFind (
2489+ epicsAddressType addrType,
2490+ const rangeItem *pRange,
2491+ /* size needed */
2492+ size_t requestSize,
2493+ /* n ls bits zero in base addr */
2494+ unsigned alignment,
2495+ /* base address found */
2496+ size_t *pBase)
2497+{
2498+ int s = SUCCESS;
2499+ size_t bb;
2500+ size_t mask;
2501+ size_t newBase;
2502+ size_t newSize;
2503+
2504+ /*
2505+ * align the block base
2506+ */
2507+ mask = devCreateMask (alignment);
2508+ newBase = pRange->begin;
2509+ if ( mask & newBase ) {
2510+ newBase |= mask;
2511+ newBase++;
2512+ }
2513+
2514+ if ( requestSize == 0) {
2515+ return S_dev_badRequest;
2516+ }
2517+
2518+ /*
2519+ * align size of block
2520+ */
2521+ newSize = requestSize;
2522+ if (mask & newSize) {
2523+ newSize |= mask;
2524+ newSize++;
2525+ }
2526+
2527+ if (pRange->end - pRange->begin + 1 < newSize) {
2528+ return S_dev_badRequest;
2529+ }
2530+
2531+ bb = pRange->begin;
2532+ while (bb <= (pRange->end + 1) - newSize) {
2533+ s = devNoResponseProbe (addrType, bb, newSize);
2534+ if (s==SUCCESS) {
2535+ *pBase = bb;
2536+ return SUCCESS;
2537+ }
2538+ bb += newSize;
2539+ }
2540+
2541+ return s;
2542+}
2543+
2544+/*
2545+ * devNoResponseProbe()
2546+ */
2547+long devNoResponseProbe (epicsAddressType addrType,
2548+ size_t base, size_t size)
2549+{
2550+ volatile void *pPhysical;
2551+ size_t probe;
2552+ size_t byteNo;
2553+ unsigned wordSize;
2554+ union {
2555+ char charWord;
2556+ short shortWord;
2557+ int intWord;
2558+ long longWord;
2559+ }allWordSizes;
2560+ long s;
2561+
2562+ if (!devLibInitFlag) {
2563+ s = devLibInit();
2564+ if (s) {
2565+ return s;
2566+ }
2567+ }
2568+
2569+ byteNo = 0;
2570+ while (byteNo < size) {
2571+
2572+ probe = base + byteNo;
2573+
2574+ /*
2575+ * for all word sizes
2576+ */
2577+ for (wordSize=1; wordSize<=sizeof(allWordSizes); wordSize <<= 1) {
2578+ /*
2579+ * only check naturally aligned words
2580+ */
2581+ if ( (probe&(wordSize-1)) != 0 ) {
2582+ break;
2583+ }
2584+
2585+ if (byteNo+wordSize>size) {
2586+ break;
2587+ }
2588+
2589+ /*
2590+ * every byte in the block must
2591+ * map to a physical address
2592+ */
2593+ s = (*pdevLibVME->pDevMapAddr) (addrType, 0, probe, wordSize, &pPhysical);
2594+ if (s!=SUCCESS) {
2595+ return s;
2596+ }
2597+
2598+ /*
2599+ * verify that no device is present
2600+ */
2601+ s = (*pdevLibVME->pDevReadProbe)(wordSize, pPhysical, &allWordSizes);
2602+ if (s==SUCCESS) {
2603+ return S_dev_addressOverlap;
2604+ }
2605+ }
2606+ byteNo++;
2607+ }
2608+ return SUCCESS;
2609+}
2610+
2611+long devConnectInterruptVME(
2612+unsigned vectorNumber,
2613+void (*pFunction)(void *),
2614+void *parameter )
2615+{
2616+ long status;
2617+
2618+ if (!devLibInitFlag) {
2619+ status = devLibInit();
2620+ if (status) {
2621+ return status;
2622+ }
2623+ }
2624+
2625+ return (*pdevLibVME->pDevConnectInterruptVME) (vectorNumber,
2626+ pFunction, parameter);
2627+}
2628+
2629+long devDisconnectInterruptVME(
2630+unsigned vectorNumber,
2631+void (*pFunction)(void *) )
2632+{
2633+ long status;
2634+
2635+ if (!devLibInitFlag) {
2636+ status = devLibInit();
2637+ if (status) {
2638+ return status;
2639+ }
2640+ }
2641+
2642+ return (*pdevLibVME->pDevDisconnectInterruptVME) (vectorNumber, pFunction);
2643+}
2644+
2645+int devInterruptInUseVME (unsigned level)
2646+{
2647+ long status;
2648+
2649+ if (!devLibInitFlag) {
2650+ status = devLibInit();
2651+ if (status) {
2652+ return status;
2653+ }
2654+ }
2655+
2656+ return (*pdevLibVME->pDevInterruptInUseVME) (level);
2657+}
2658+
2659+long devEnableInterruptLevelVME (unsigned level)
2660+{
2661+ long status;
2662+
2663+ if (!devLibInitFlag) {
2664+ status = devLibInit();
2665+ if (status) {
2666+ return status;
2667+ }
2668+ }
2669+
2670+ return (*pdevLibVME->pDevEnableInterruptLevelVME) (level);
2671+}
2672+
2673+long devDisableInterruptLevelVME (unsigned level)
2674+{
2675+ long status;
2676+
2677+ if (!devLibInitFlag) {
2678+ status = devLibInit();
2679+ if (status) {
2680+ return status;
2681+ }
2682+ }
2683+
2684+ return (*pdevLibVME->pDevDisableInterruptLevelVME) (level);
2685+}
2686+
2687+/*
2688+ * devConnectInterrupt ()
2689+ *
2690+ * !! DEPRECATED !!
2691+ */
2692+long devConnectInterrupt(
2693+epicsInterruptType intType,
2694+unsigned vectorNumber,
2695+void (*pFunction)(void *),
2696+void *parameter)
2697+{
2698+ long status;
2699+
2700+ if (!devLibInitFlag) {
2701+ status = devLibInit();
2702+ if (status) {
2703+ return status;
2704+ }
2705+ }
2706+
2707+ switch(intType){
2708+ case intVME:
2709+ case intVXI:
2710+ return (*pdevLibVME->pDevConnectInterruptVME) (vectorNumber,
2711+ pFunction, parameter);
2712+ default:
2713+ return S_dev_uknIntType;
2714+ }
2715+}
2716+
2717+/*
2718+ *
2719+ * devDisconnectInterrupt()
2720+ *
2721+ * !! DEPRECATED !!
2722+ */
2723+long devDisconnectInterrupt(
2724+epicsInterruptType intType,
2725+unsigned vectorNumber,
2726+void (*pFunction)(void *)
2727+)
2728+{
2729+ long status;
2730+
2731+ if (!devLibInitFlag) {
2732+ status = devLibInit();
2733+ if (status) {
2734+ return status;
2735+ }
2736+ }
2737+
2738+ switch(intType){
2739+ case intVME:
2740+ case intVXI:
2741+ return (*pdevLibVME->pDevDisconnectInterruptVME) (vectorNumber,
2742+ pFunction);
2743+ default:
2744+ return S_dev_uknIntType;
2745+ }
2746+}
2747+
2748+/*
2749+ * devEnableInterruptLevel()
2750+ *
2751+ * !! DEPRECATED !!
2752+ */
2753+long devEnableInterruptLevel(
2754+epicsInterruptType intType,
2755+unsigned level)
2756+{
2757+ long status;
2758+
2759+ if (!devLibInitFlag) {
2760+ status = devLibInit();
2761+ if (status) {
2762+ return status;
2763+ }
2764+ }
2765+
2766+ switch(intType){
2767+ case intVME:
2768+ case intVXI:
2769+ return (*pdevLibVME->pDevEnableInterruptLevelVME) (level);
2770+ default:
2771+ return S_dev_uknIntType;
2772+ }
2773+}
2774+
2775+/*
2776+ * devDisableInterruptLevel()
2777+ *
2778+ * !! DEPRECATED !!
2779+ */
2780+long devDisableInterruptLevel (
2781+epicsInterruptType intType,
2782+unsigned level)
2783+{
2784+ long status;
2785+
2786+ if (!devLibInitFlag) {
2787+ status = devLibInit();
2788+ if (status) {
2789+ return status;
2790+ }
2791+ }
2792+
2793+ switch(intType){
2794+ case intVME:
2795+ case intVXI:
2796+ return (*pdevLibVME->pDevDisableInterruptLevelVME) (level);
2797+ default:
2798+ return S_dev_uknIntType;
2799+ }
2800+}
2801+
2802+/*
2803+ * locationProbe
2804+ *
2805+ * !! DEPRECATED !!
2806+ */
2807+long locationProbe (epicsAddressType addrType, char *pLocation)
2808+{
2809+ return devNoResponseProbe (addrType, (size_t) pLocation, sizeof(long));
2810+}
2811+
2812+/******************************************************************************
2813+ *
2814+ * The follwing may, or may not be present in the BSP for the CPU in use.
2815+ *
2816+ */
2817+/******************************************************************************
2818+ *
2819+ * Routines to use to allocate and free memory present in the A24 region.
2820+ *
2821+ ******************************************************************************/
2822+
2823+int devLibA24Debug = 0; /* Debugging flag */
2824+
2825+void *devLibA24Calloc(size_t size)
2826+{
2827+ void *ret;
2828+
2829+ ret = devLibA24Malloc(size);
2830+
2831+ if (ret == NULL)
2832+ return (NULL);
2833+
2834+ memset(ret, 0x00, size);
2835+ return(ret);
2836+}
2837+
2838+void *devLibA24Malloc(size_t size)
2839+{
2840+ void *ret;
2841+
2842+ if (devLibA24Debug)
2843+ epicsPrintf ("devLibA24Malloc(%u) entered\n", (unsigned int)size);
2844+
2845+ ret = pdevLibVME->pDevA24Malloc(size);
2846+ return(ret);
2847+}
2848+
2849+void devLibA24Free(void *pBlock)
2850+{
2851+ if (devLibA24Debug)
2852+ epicsPrintf("devLibA24Free(%p) entered\n", pBlock);
2853+
2854+ pdevLibVME->pDevA24Free(pBlock);
2855+}
2856
2857=== added file 'src/libCom/osi/devLibVME.h'
2858--- src/libCom/osi/devLibVME.h 1970-01-01 00:00:00 +0000
2859+++ src/libCom/osi/devLibVME.h 2010-05-28 11:06:32 +0000
2860@@ -0,0 +1,312 @@
2861+/*************************************************************************\
2862+* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
2863+* National Laboratory.
2864+* Copyright (c) 2002 The Regents of the University of California, as
2865+* Operator of Los Alamos National Laboratory.
2866+* EPICS BASE is distributed subject to a Software License Agreement found
2867+* in file LICENSE that is included with this distribution.
2868+\*************************************************************************/
2869+/* devLib.h */
2870+/* devLib.h,v 1.1.2.8 2009/07/09 15:27:43 anj Exp */
2871+
2872+/*
2873+ * Original Author: Marty Kraimer
2874+ * Author: Jeff Hill
2875+ * Date: 03-10-93
2876+ */
2877+
2878+#ifndef INCdevLibh
2879+#define INCdevLibh 1
2880+
2881+#include "dbDefs.h"
2882+#include "osdVME.h"
2883+#include "errMdef.h"
2884+#include "shareLib.h"
2885+#include "devLib.h"
2886+
2887+#ifdef __cplusplus
2888+extern "C" {
2889+#endif
2890+
2891+/*
2892+ * epdevAddressType & EPICStovxWorksAddrType
2893+ * devLib.c must change in unison
2894+ */
2895+typedef enum {
2896+ atVMEA16,
2897+ atVMEA24,
2898+ atVMEA32,
2899+ atISA, /* memory mapped ISA access (until now only on PC) */
2900+ atVMECSR, /* VME-64 CR/CSR address space */
2901+ atLast /* atLast must be the last enum in this list */
2902+ } epicsAddressType;
2903+
2904+/*
2905+ * pointer to an array of strings for each of
2906+ * the above address types
2907+ */
2908+epicsShareExtern const char *epicsAddressTypeName[];
2909+
2910+#ifdef __cplusplus
2911+}
2912+#endif
2913+
2914+/*
2915+ * To retain compatibility include everything by default
2916+ */
2917+#ifndef NO_DEVLIB_COMPAT
2918+# include "devLibVMEImpl.h"
2919+#endif
2920+
2921+#ifdef __cplusplus
2922+extern "C" {
2923+#endif
2924+
2925+/*
2926+ * General API
2927+ *
2928+ * This section applies to all bus types
2929+ */
2930+
2931+epicsShareFunc long devAddressMap(void); /* print an address map */
2932+
2933+/*
2934+ * devBusToLocalAddr()
2935+ *
2936+ * OSI routine to translate bus addresses their local CPU address mapping
2937+ */
2938+epicsShareFunc long devBusToLocalAddr (
2939+ epicsAddressType addrType,
2940+ size_t busAddr,
2941+ volatile void **ppLocalAddr);
2942+/*
2943+ * devReadProbe()
2944+ *
2945+ * a bus error safe "wordSize" read at the specified address which returns
2946+ * unsuccessful status if the device isnt present
2947+ */
2948+epicsShareFunc long devReadProbe (
2949+ unsigned wordSize, volatile const void *ptr, void *pValueRead);
2950+
2951+/*
2952+ * devNoResponseProbe()
2953+ *
2954+ * Verifies that no devices respond at naturally aligned words
2955+ * within the specified address range. Return success if no devices
2956+ * respond. Returns an error if a device does respond or if
2957+ * a physical address for a naturally aligned word cant be mapped.
2958+ * Checks all naturally aligned word sizes between char and long for
2959+ * the entire specified range of bytes.
2960+ */
2961+epicsShareFunc long devNoResponseProbe(
2962+ epicsAddressType addrType,
2963+ size_t base,
2964+ size_t size
2965+);
2966+
2967+/*
2968+ * devWriteProbe
2969+ *
2970+ * a bus error safe "wordSize" write at the specified address which returns
2971+ * unsuccessful status if the device isnt present
2972+ */
2973+epicsShareFunc long devWriteProbe (
2974+ unsigned wordSize, volatile void *ptr, const void *pValueWritten);
2975+
2976+epicsShareFunc long devRegisterAddress(
2977+ const char *pOwnerName,
2978+ epicsAddressType addrType,
2979+ size_t logicalBaseAddress,
2980+ size_t size, /* bytes */
2981+ volatile void **pPhysicalAddress);
2982+
2983+epicsShareFunc long devUnregisterAddress(
2984+ epicsAddressType addrType,
2985+ size_t logicalBaseAddress,
2986+ const char *pOwnerName);
2987+
2988+/*
2989+ * allocate and register an unoccupied address block
2990+ */
2991+epicsShareFunc long devAllocAddress(
2992+ const char *pOwnerName,
2993+ epicsAddressType addrType,
2994+ size_t size,
2995+ unsigned alignment, /*n ls bits zero in addr*/
2996+ volatile void **pLocalAddress);
2997+
2998+/*
2999+ * VME API
3000+ *
3001+ * Functions in this section apply only to the VME bus type
3002+ */
3003+
3004+/*
3005+ * connect ISR to a VME interrupt vector
3006+ */
3007+epicsShareFunc long devConnectInterruptVME(
3008+ unsigned vectorNumber,
3009+ void (*pFunction)(void *),
3010+ void *parameter);
3011+
3012+/*
3013+ * disconnect ISR from a VME interrupt vector
3014+ *
3015+ * The parameter pFunction should be set to the C function pointer that
3016+ * was connected. It is used as a key to prevent a driver from inadvertently
3017+ * removing an interrupt handler that it didn't install
3018+ */
3019+epicsShareFunc long devDisconnectInterruptVME(
3020+ unsigned vectorNumber,
3021+ void (*pFunction)(void *));
3022+
3023+/*
3024+ * determine if a VME interrupt vector is in use
3025+ *
3026+ * returns boolean
3027+ */
3028+epicsShareFunc int devInterruptInUseVME (unsigned vectorNumber);
3029+
3030+/*
3031+ * enable VME interrupt level
3032+ */
3033+epicsShareFunc long devEnableInterruptLevelVME (unsigned level);
3034+
3035+/*
3036+ * disable VME interrupt level
3037+ */
3038+epicsShareFunc long devDisableInterruptLevelVME (unsigned level);
3039+
3040+/*
3041+ * Routines to allocate and free memory in the A24 memory region.
3042+ *
3043+ */
3044+epicsShareFunc void *devLibA24Malloc(size_t);
3045+epicsShareFunc void *devLibA24Calloc(size_t);
3046+epicsShareFunc void devLibA24Free(void *pBlock);
3047+
3048+/*
3049+ * ISA API
3050+ *
3051+ * Functions in this section apply only to the ISA bus type
3052+ */
3053+
3054+/*
3055+ * connect ISR to an ISA interrupt level
3056+ * (not implemented)
3057+ * (API should be reviewed)
3058+ */
3059+epicsShareFunc long devConnectInterruptISA(
3060+ unsigned interruptLevel,
3061+ void (*pFunction)(void *),
3062+ void *parameter);
3063+
3064+/*
3065+ * disconnect ISR from an ISA interrupt level
3066+ * (not implemented)
3067+ * (API should be reviewed)
3068+ *
3069+ * The parameter pFunction should be set to the C function pointer that
3070+ * was connected. It is used as a key to prevent a driver from inadvertently
3071+ * removing an interrupt handler that it didn't install
3072+ */
3073+epicsShareFunc long devDisconnectInterruptISA(
3074+ unsigned interruptLevel,
3075+ void (*pFunction)(void *));
3076+
3077+/*
3078+ * determine if an ISA interrupt level is in use
3079+ * (not implemented)
3080+ *
3081+ * returns boolean
3082+ */
3083+epicsShareFunc int devInterruptLevelInUseISA (unsigned interruptLevel);
3084+
3085+/*
3086+ * enable ISA interrupt level
3087+ */
3088+epicsShareFunc long devEnableInterruptLevelISA (unsigned level);
3089+
3090+/*
3091+ * disable ISA interrupt level
3092+ */
3093+epicsShareFunc long devDisableInterruptLevelISA (unsigned level);
3094+
3095+/*
3096+ * Deprecated interface
3097+ */
3098+
3099+#ifndef NO_DEVLIB_OLD_INTERFACE
3100+
3101+typedef enum {intVME, intVXI, intISA} epicsInterruptType;
3102+
3103+/*
3104+ * NOTE: this routine has been deprecated. It exists
3105+ * for backwards compatibility purposes only.
3106+ *
3107+ * Please use one of devConnectInterruptVME, devConnectInterruptPCI,
3108+ * devConnectInterruptISA etc. devConnectInterrupt will be removed
3109+ * in a future release.
3110+ */
3111+epicsShareFunc long devConnectInterrupt(
3112+ epicsInterruptType intType,
3113+ unsigned vectorNumber,
3114+ void (*pFunction)(void *),
3115+ void *parameter);
3116+
3117+/*
3118+ * NOTE: this routine has been deprecated. It exists
3119+ * for backwards compatibility purposes only.
3120+ *
3121+ * Please use one of devDisconnectInterruptVME, devDisconnectInterruptPCI,
3122+ * devDisconnectInterruptISA etc. devDisconnectInterrupt will be removed
3123+ * in a future release.
3124+ */
3125+epicsShareFunc long devDisconnectInterrupt(
3126+ epicsInterruptType intType,
3127+ unsigned vectorNumber,
3128+ void (*pFunction)(void *));
3129+
3130+/*
3131+ * NOTE: this routine has been deprecated. It exists
3132+ * for backwards compatibility purposes only.
3133+ *
3134+ * Please use one of devEnableInterruptLevelVME, devEnableInterruptLevelPCI,
3135+ * devEnableInterruptLevelISA etc. devEnableInterruptLevel will be removed
3136+ * in a future release.
3137+ */
3138+epicsShareFunc long devEnableInterruptLevel(
3139+ epicsInterruptType intType, unsigned level);
3140+
3141+/*
3142+ * NOTE: this routine has been deprecated. It exists
3143+ * for backwards compatibility purposes only.
3144+ *
3145+ * Please use one of devDisableInterruptLevelVME, devDisableInterruptLevelISA,
3146+ * devDisableInterruptLevelPCI etc. devDisableInterruptLevel will be removed
3147+ * in a future release.
3148+ */
3149+epicsShareFunc long devDisableInterruptLevel (
3150+ epicsInterruptType intType, unsigned level);
3151+
3152+/*
3153+ * NOTE: this routine has been deprecated. It exists
3154+ * for backwards compatibility purposes only.
3155+ *
3156+ * Please use devNoResponseProbe(). locationProbe() will be removed
3157+ * in a future release.
3158+ */
3159+epicsShareFunc long locationProbe (epicsAddressType addrType, char *pLocation);
3160+
3161+#endif /* NO_DEVLIB_OLD_INTERFACE */
3162+
3163+/*
3164+ * Some vxWorks convenience routines
3165+ */
3166+void bcopyLongs(char *source, char *destination, int nlongs);
3167+
3168+#ifdef __cplusplus
3169+}
3170+#endif
3171+
3172+#endif /* INCdevLibh.h*/
3173
3174=== added file 'src/libCom/osi/devLibVMEImpl.h'
3175--- src/libCom/osi/devLibVMEImpl.h 1970-01-01 00:00:00 +0000
3176+++ src/libCom/osi/devLibVMEImpl.h 2010-05-28 11:06:32 +0000
3177@@ -0,0 +1,104 @@
3178+/*************************************************************************\
3179+* Copyright (c) 2010 Brookhaven Science Associates, as Operator of
3180+* Brookhaven National Laboratory.
3181+* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
3182+* National Laboratory.
3183+* Copyright (c) 2002 The Regents of the University of California, as
3184+* Operator of Los Alamos National Laboratory.
3185+* EPICS BASE is distributed subject to a Software License Agreement found
3186+* in file LICENSE that is included with this distribution.
3187+\*************************************************************************/
3188+/* devLibImpl.h */
3189+/* */
3190+
3191+/*
3192+ * Original Author: Marty Kraimer
3193+ * Author: Jeff Hill
3194+ * Date: 03-10-93
3195+ */
3196+
3197+#ifndef INCdevLibImplh
3198+#define INCdevLibImplh 1
3199+
3200+#include "dbDefs.h"
3201+#include "shareLib.h"
3202+#include "devLib.h"
3203+
3204+#ifdef __cplusplus
3205+extern "C" {
3206+#endif
3207+
3208+/*
3209+ * virtual OS layer for devLib.c
3210+ *
3211+ * The global virtual OS table pdevLibVME controls
3212+ * the behaviour of the functions defined in devLib.h.
3213+ * All of which call into the functions found in this table
3214+ * to perform system specific tasks.
3215+ */
3216+typedef struct devLibVME {
3217+ /*
3218+ * maps logical address to physical address, but does not detect
3219+ * two device drivers that are using the same address range
3220+ */
3221+ long (*pDevMapAddr) (epicsAddressType addrType, unsigned options,
3222+ size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
3223+
3224+ /*
3225+ * a bus error safe "wordSize" read at the specified address which returns
3226+ * unsuccessful status if the device isnt present
3227+ */
3228+ long (*pDevReadProbe) (unsigned wordSize, volatile const void *ptr, void *pValueRead);
3229+
3230+ /*
3231+ * a bus error safe "wordSize" write at the specified address which returns
3232+ * unsuccessful status if the device isnt present
3233+ */
3234+ long (*pDevWriteProbe) (unsigned wordSize, volatile void *ptr, const void *pValueWritten);
3235+
3236+ /*
3237+ * connect ISR to a VME interrupt vector
3238+ * (required for backwards compatibility)
3239+ */
3240+ long (*pDevConnectInterruptVME) (unsigned vectorNumber,
3241+ void (*pFunction)(void *), void *parameter);
3242+
3243+ /*
3244+ * disconnect ISR from a VME interrupt vector
3245+ * (required for backwards compatibility)
3246+ */
3247+ long (*pDevDisconnectInterruptVME) (unsigned vectorNumber,
3248+ void (*pFunction)(void *));
3249+
3250+ /*
3251+ * enable VME interrupt level
3252+ */
3253+ long (*pDevEnableInterruptLevelVME) (unsigned level);
3254+
3255+ /*
3256+ * disable VME interrupt level
3257+ */
3258+ long (*pDevDisableInterruptLevelVME) (unsigned level);
3259+ /* malloc/free A24 address space */
3260+ void *(*pDevA24Malloc)(size_t nbytes);
3261+ void (*pDevA24Free)(void *pBlock);
3262+ long (*pDevInit)(void);
3263+
3264+ /*
3265+ * test if VME interrupt has an ISR connected
3266+ */
3267+ int (*pDevInterruptInUseVME) (unsigned vectorNumber);
3268+}devLibVME;
3269+
3270+epicsShareExtern devLibVME *pdevLibVME;
3271+
3272+#ifndef NO_DEVLIB_COMPAT
3273+# define pdevLibVirtualOS pdevLibVME
3274+#endif
3275+
3276+
3277+#ifdef __cplusplus
3278+}
3279+#endif
3280+
3281+#endif /* INCdevLibImplh */
3282
3283=== removed file 'src/libCom/osi/os/RTEMS/devLibOSD.c'
3284--- src/libCom/osi/os/RTEMS/devLibOSD.c 2009-07-09 16:37:24 +0000
3285+++ src/libCom/osi/os/RTEMS/devLibOSD.c 1970-01-01 00:00:00 +0000
3286@@ -1,350 +0,0 @@
3287-/*************************************************************************\
3288-* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
3289-* National Laboratory.
3290-* Copyright (c) 2002 The Regents of the University of California, as
3291-* Operator of Los Alamos National Laboratory.
3292-* EPICS BASE is distributed subject to a Software License Agreement found
3293-* in file LICENSE that is included with this distribution.
3294-\*************************************************************************/
3295-/* $Id$ */
3296-
3297-/* RTEMS port by Till Straumann, <strauman@slac.stanford.edu>
3298- * 3/2002
3299- *
3300- */
3301-
3302-#include <epicsStdio.h>
3303-#include <epicsExit.h>
3304-#include <rtems.h>
3305-#include <bsp.h>
3306-#include "devLib.h"
3307-#include <epicsInterrupt.h>
3308-
3309-#if defined(__PPC__) || defined(__mcf528x__)
3310-
3311-#if defined(__PPC__)
3312-#include <bsp/VME.h>
3313-#include <bsp/bspExt.h>
3314-#endif
3315-
3316-
3317-typedef void myISR (void *pParam);
3318-
3319-static myISR *isrFetch(unsigned vectorNumber, void **parg);
3320-
3321-/*
3322- * this routine needs to be in the symbol table
3323- * for this code to work correctly
3324- */
3325-void unsolicitedHandlerEPICS(int vectorNumber);
3326-
3327-static myISR *defaultHandlerAddr[]={
3328- (myISR*)unsolicitedHandlerEPICS,
3329-};
3330-
3331-/*
3332- * Make sure that the CR/CSR addressing mode is defined.
3333- * (it may not be in some BSPs).
3334- */
3335-#ifndef VME_AM_CSR
3336-# define VME_AM_CSR (0x2f)
3337-#endif
3338-
3339-/*
3340- * we use a translation between an EPICS encoding
3341- * and a vxWorks encoding here
3342- * to reduce dependency of drivers on vxWorks
3343- *
3344- * we assume that the BSP are configured to use these
3345- * address modes by default
3346- */
3347-#define EPICSAddrTypeNoConvert -1
3348-int EPICStovxWorksAddrType[]
3349- = {
3350- VME_AM_SUP_SHORT_IO,
3351- VME_AM_STD_SUP_DATA,
3352- VME_AM_EXT_SUP_DATA,
3353- EPICSAddrTypeNoConvert,
3354- VME_AM_CSR
3355- };
3356-
3357-/*
3358- * maps logical address to physical address, but does not detect
3359- * two device drivers that are using the same address range
3360- */
3361-static long rtmsDevMapAddr (epicsAddressType addrType, unsigned options,
3362- size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
3363-
3364-/*
3365- * a bus error safe "wordSize" read at the specified address which returns
3366- * unsuccessful status if the device isnt present
3367- */
3368-long rtmsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue);
3369-
3370-/*
3371- * a bus error safe "wordSize" write at the specified address which returns
3372- * unsuccessful status if the device isnt present
3373- */
3374-long rtmsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue);
3375-
3376-/* RTEMS specific init */
3377-
3378-/*devA24Malloc and devA24Free are not implemented*/
3379-static void *devA24Malloc(size_t size) { return 0;}
3380-static void devA24Free(void *pBlock) {};
3381-static long rtmsDevInit(void);
3382-
3383-/*
3384- * used by bind in devLib.c
3385- */
3386-static devLibVirtualOS rtemsVirtualOS = {
3387- rtmsDevMapAddr, rtmsDevReadProbe, rtmsDevWriteProbe,
3388- devConnectInterruptVME, devDisconnectInterruptVME,
3389- devEnableInterruptLevelVME, devDisableInterruptLevelVME,
3390- devA24Malloc,devA24Free,rtmsDevInit
3391-};
3392-devLibVirtualOS *pdevLibVirtualOS = &rtemsVirtualOS;
3393-
3394-/* RTEMS specific initialization */
3395-static long
3396-rtmsDevInit(void)
3397-{
3398- /* assume the vme bridge has been initialized by bsp */
3399- /* init BSP extensions [memProbe etc.] */
3400- return bspExtInit();
3401-}
3402-
3403-/*
3404- * devConnectInterruptVME
3405- *
3406- * wrapper to minimize driver dependency on OS
3407- */
3408-long devConnectInterruptVME (
3409- unsigned vectorNumber,
3410- void (*pFunction)(),
3411- void *parameter)
3412-{
3413- int status;
3414-
3415-
3416- if (devInterruptInUseVME(vectorNumber)) {
3417- return S_dev_vectorInUse;
3418- }
3419- status = BSP_installVME_isr(
3420- vectorNumber,
3421- pFunction,
3422- parameter);
3423- if (status) {
3424- return S_dev_vecInstlFail;
3425- }
3426-
3427- return 0;
3428-}
3429-
3430-/*
3431- *
3432- * devDisconnectInterruptVME()
3433- *
3434- * wrapper to minimize driver dependency on OS
3435- *
3436- * The parameter pFunction should be set to the C function pointer that
3437- * was connected. It is used as a key to prevent a driver from removing
3438- * an interrupt handler that was installed by another driver
3439- *
3440- */
3441-long devDisconnectInterruptVME (
3442- unsigned vectorNumber,
3443- void (*pFunction)()
3444-)
3445-{
3446- void (*psub)();
3447- void *arg;
3448- int status;
3449-
3450- /*
3451- * If pFunction not connected to this vector
3452- * then they are probably disconnecting from the wrong vector
3453- */
3454- psub = isrFetch(vectorNumber, &arg);
3455- if(psub != pFunction){
3456- return S_dev_vectorNotInUse;
3457- }
3458-
3459- status = BSP_removeVME_isr(
3460- vectorNumber,
3461- psub,
3462- arg) ||
3463- BSP_installVME_isr(
3464- vectorNumber,
3465- (BSP_VME_ISR_t)unsolicitedHandlerEPICS,
3466- (void*)vectorNumber);
3467- if(status){
3468- return S_dev_vecInstlFail;
3469- }
3470-
3471- return 0;
3472-}
3473-
3474-/*
3475- * enable VME interrupt level
3476- */
3477-long devEnableInterruptLevelVME (unsigned level)
3478-{
3479- return BSP_enableVME_int_lvl(level);
3480-}
3481-
3482-/*
3483- * disable VME interrupt level
3484- */
3485-long devDisableInterruptLevelVME (unsigned level)
3486-{
3487- return BSP_disableVME_int_lvl(level);
3488-}
3489-
3490-/*
3491- * rtmsDevMapAddr ()
3492- */
3493-static long rtmsDevMapAddr (epicsAddressType addrType, unsigned options,
3494- size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress)
3495-{
3496- long status;
3497-
3498- if (ppPhysicalAddress==NULL) {
3499- return S_dev_badArgument;
3500- }
3501-
3502- if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert)
3503- {
3504- *ppPhysicalAddress = (void *) logicalAddress;
3505- }
3506- else
3507- {
3508- status = BSP_vme2local_adrs(EPICStovxWorksAddrType[addrType],
3509- logicalAddress, (unsigned long *)ppPhysicalAddress);
3510- if (status) {
3511- return S_dev_addrMapFail;
3512- }
3513- }
3514-
3515- return 0;
3516-}
3517-
3518-/*
3519- * a bus error safe "wordSize" read at the specified address which returns
3520- * unsuccessful status if the device isnt present
3521- */
3522-rtems_status_code bspExtMemProbe(void *addr, int write, int size, void *pval);
3523-long rtmsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue)
3524-{
3525- long status;
3526-
3527- /*
3528- * this global variable exists in the nivxi library
3529- */
3530- status = bspExtMemProbe ((void*)ptr, 0/*read*/, wordSize, pValue);
3531- if (status!=RTEMS_SUCCESSFUL) {
3532- return S_dev_noDevice;
3533- }
3534-
3535- return 0;
3536-}
3537-
3538-/*
3539- * a bus error safe "wordSize" write at the specified address which returns
3540- * unsuccessful status if the device isnt present
3541- */
3542-long rtmsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue)
3543-{
3544- long status;
3545-
3546- /*
3547- * this global variable exists in the nivxi library
3548- */
3549- status = bspExtMemProbe ((void*)ptr, 1/*write*/, wordSize, (void*)pValue);
3550- if (status!=RTEMS_SUCCESSFUL) {
3551- return S_dev_noDevice;
3552- }
3553-
3554- return 0;
3555-}
3556-
3557-/*
3558- * isrFetch()
3559- */
3560-static myISR *isrFetch(unsigned vectorNumber, void **parg)
3561-{
3562- /*
3563- * fetch the handler or C stub attached at this vector
3564- */
3565- return (myISR *) BSP_getVME_isr(vectorNumber,parg);
3566-}
3567-
3568-/*
3569- * determine if a VME interrupt vector is in use
3570- */
3571-int devInterruptInUseVME (unsigned vectorNumber)
3572-{
3573- int i;
3574- myISR *psub;
3575- void *arg;
3576-
3577- psub = isrFetch (vectorNumber,&arg);
3578-
3579- if (!psub)
3580- return FALSE;
3581-
3582- /*
3583- * its a C routine. Does it match a default handler?
3584- */
3585- for (i=0; i<NELEMENTS(defaultHandlerAddr); i++) {
3586- if (defaultHandlerAddr[i] == psub) {
3587- return FALSE;
3588- }
3589- }
3590-
3591- return TRUE;
3592-}
3593-
3594-
3595-/*
3596- * unsolicitedHandlerEPICS()
3597- * what gets called if they disconnect from an
3598- * interrupt and an interrupt arrives on the
3599- * disconnected vector
3600- *
3601- * NOTE: RTEMS may pass additional arguments - hope
3602- * this doesn't disturb this handler...
3603- *
3604- * A cleaner way would be having a OS dependent
3605- * macro to declare handler prototypes...
3606- *
3607- */
3608-void unsolicitedHandlerEPICS(int vectorNumber)
3609-{
3610- /*
3611- * call epicInterruptContextMessage()
3612- * and not errMessage()
3613- * so we are certain that printf()
3614- * does not get called at interrupt level
3615- *
3616- * NOTE: current RTEMS implementation only
3617- * allows a static string to be passed
3618- */
3619- epicsInterruptContextMessage(
3620- "Interrupt to EPICS disconnected vector"
3621- );
3622-}
3623-
3624-#endif /* defined(__PPC__) && defined(mpc750) */
3625-
3626-/*
3627- * Some vxWorks convenience routines
3628- */
3629-void
3630-bcopyLongs(char *source, char *destination, int nlongs)
3631-{
3632- const long *s = (long *)source;
3633- long *d = (long *)destination;
3634- while(nlongs--)
3635- *d++ = *s++;
3636-}
3637
3638=== added file 'src/libCom/osi/os/RTEMS/devLibVMEOSD.c'
3639--- src/libCom/osi/os/RTEMS/devLibVMEOSD.c 1970-01-01 00:00:00 +0000
3640+++ src/libCom/osi/os/RTEMS/devLibVMEOSD.c 2010-05-28 11:06:32 +0000
3641@@ -0,0 +1,366 @@
3642+/*************************************************************************\
3643+* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
3644+* National Laboratory.
3645+* Copyright (c) 2002 The Regents of the University of California, as
3646+* Operator of Los Alamos National Laboratory.
3647+* EPICS BASE is distributed subject to a Software License Agreement found
3648+* in file LICENSE that is included with this distribution.
3649+\*************************************************************************/
3650+/* $Id$ */
3651+
3652+/* RTEMS port by Till Straumann, <strauman@slac.stanford.edu>
3653+ * 3/2002
3654+ *
3655+ */
3656+
3657+#include <epicsStdio.h>
3658+#include <epicsExit.h>
3659+#include <rtems.h>
3660+#include <bsp.h>
3661+#include "devLibVME.h"
3662+#include <epicsInterrupt.h>
3663+
3664+#if defined(__PPC__) || defined(__mcf528x__)
3665+
3666+#if defined(__PPC__)
3667+#include <bsp/VME.h>
3668+#include <bsp/bspExt.h>
3669+#endif
3670+
3671+
3672+typedef void myISR (void *pParam);
3673+
3674+static myISR *isrFetch(unsigned vectorNumber, void **parg);
3675+
3676+/*
3677+ * this routine needs to be in the symbol table
3678+ * for this code to work correctly
3679+ */
3680+static void unsolicitedHandlerEPICS(int vectorNumber);
3681+
3682+static myISR *defaultHandlerAddr[]={
3683+ (myISR*)unsolicitedHandlerEPICS,
3684+};
3685+
3686+/*
3687+ * Make sure that the CR/CSR addressing mode is defined.
3688+ * (it may not be in some BSPs).
3689+ */
3690+#ifndef VME_AM_CSR
3691+# define VME_AM_CSR (0x2f)
3692+#endif
3693+
3694+/*
3695+ * we use a translation between an EPICS encoding
3696+ * and a vxWorks encoding here
3697+ * to reduce dependency of drivers on vxWorks
3698+ *
3699+ * we assume that the BSP are configured to use these
3700+ * address modes by default
3701+ */
3702+#define EPICSAddrTypeNoConvert -1
3703+int EPICStovxWorksAddrType[]
3704+ = {
3705+ VME_AM_SUP_SHORT_IO,
3706+ VME_AM_STD_SUP_DATA,
3707+ VME_AM_EXT_SUP_DATA,
3708+ EPICSAddrTypeNoConvert,
3709+ VME_AM_CSR
3710+ };
3711+
3712+/*
3713+ * maps logical address to physical address, but does not detect
3714+ * two device drivers that are using the same address range
3715+ */
3716+static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options,
3717+ size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
3718+
3719+/*
3720+ * a bus error safe "wordSize" read at the specified address which returns
3721+ * unsuccessful status if the device isnt present
3722+ */
3723+static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue);
3724+
3725+/*
3726+ * a bus error safe "wordSize" write at the specified address which returns
3727+ * unsuccessful status if the device isnt present
3728+ */
3729+static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue);
3730+
3731+static long rtemsDevConnectInterruptVME (
3732+ unsigned vectorNumber,
3733+ void (*pFunction)(),
3734+ void *parameter);
3735+
3736+static long rtemsDevDisconnectInterruptVME (
3737+ unsigned vectorNumber,
3738+ void (*pFunction)()
3739+);
3740+
3741+static long rtemsDevEnableInterruptLevelVME (unsigned level);
3742+
3743+static long rtemsDevDisableInterruptLevelVME (unsigned level);
3744+
3745+static int rtemsDevInterruptInUseVME (unsigned vectorNumber);
3746+
3747+/* RTEMS specific init */
3748+
3749+/*devA24Malloc and devA24Free are not implemented*/
3750+static void *devA24Malloc(size_t size) { return 0;}
3751+static void devA24Free(void *pBlock) {};
3752+static long rtemsDevInit(void);
3753+
3754+/*
3755+ * used by bind in devLib.c
3756+ */
3757+static devLibVME rtemsVirtualOS = {
3758+ rtemsDevMapAddr, rtemsDevReadProbe, rtemsDevWriteProbe,
3759+ rtemsDevConnectInterruptVME, rtemsDevDisconnectInterruptVME,
3760+ rtemsDevEnableInterruptLevelVME, rtemsDevDisableInterruptLevelVME,
3761+ devA24Malloc,devA24Free,rtemsDevInit,rtemsDevInterruptInUseVME
3762+};
3763+devLibVME *pdevLibVME = &rtemsVirtualOS;
3764+
3765+/* RTEMS specific initialization */
3766+static long
3767+rtemsDevInit(void)
3768+{
3769+ /* assume the vme bridge has been initialized by bsp */
3770+ /* init BSP extensions [memProbe etc.] */
3771+ return bspExtInit();
3772+}
3773+
3774+/*
3775+ * devConnectInterruptVME
3776+ *
3777+ * wrapper to minimize driver dependency on OS
3778+ */
3779+static long rtemsDevConnectInterruptVME (
3780+ unsigned vectorNumber,
3781+ void (*pFunction)(),
3782+ void *parameter)
3783+{
3784+ int status;
3785+
3786+
3787+ if (devInterruptInUseVME(vectorNumber)) {
3788+ return S_dev_vectorInUse;
3789+ }
3790+ status = BSP_installVME_isr(
3791+ vectorNumber,
3792+ pFunction,
3793+ parameter);
3794+ if (status) {
3795+ return S_dev_vecInstlFail;
3796+ }
3797+
3798+ return 0;
3799+}
3800+
3801+/*
3802+ *
3803+ * devDisconnectInterruptVME()
3804+ *
3805+ * wrapper to minimize driver dependency on OS
3806+ *
3807+ * The parameter pFunction should be set to the C function pointer that
3808+ * was connected. It is used as a key to prevent a driver from removing
3809+ * an interrupt handler that was installed by another driver
3810+ *
3811+ */
3812+static long rtemsDevDisconnectInterruptVME (
3813+ unsigned vectorNumber,
3814+ void (*pFunction)()
3815+)
3816+{
3817+ void (*psub)();
3818+ void *arg;
3819+ int status;
3820+
3821+ /*
3822+ * If pFunction not connected to this vector
3823+ * then they are probably disconnecting from the wrong vector
3824+ */
3825+ psub = isrFetch(vectorNumber, &arg);
3826+ if(psub != pFunction){
3827+ return S_dev_vectorNotInUse;
3828+ }
3829+
3830+ status = BSP_removeVME_isr(
3831+ vectorNumber,
3832+ psub,
3833+ arg) ||
3834+ BSP_installVME_isr(
3835+ vectorNumber,
3836+ (BSP_VME_ISR_t)unsolicitedHandlerEPICS,
3837+ (void*)vectorNumber);
3838+ if(status){
3839+ return S_dev_vecInstlFail;
3840+ }
3841+
3842+ return 0;
3843+}
3844+
3845+/*
3846+ * enable VME interrupt level
3847+ */
3848+static long rtemsDevEnableInterruptLevelVME (unsigned level)
3849+{
3850+ return BSP_enableVME_int_lvl(level);
3851+}
3852+
3853+/*
3854+ * disable VME interrupt level
3855+ */
3856+static long rtemsDevDisableInterruptLevelVME (unsigned level)
3857+{
3858+ return BSP_disableVME_int_lvl(level);
3859+}
3860+
3861+/*
3862+ * rtemsDevMapAddr ()
3863+ */
3864+static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options,
3865+ size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress)
3866+{
3867+ long status;
3868+
3869+ if (ppPhysicalAddress==NULL) {
3870+ return S_dev_badArgument;
3871+ }
3872+
3873+ if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert)
3874+ {
3875+ *ppPhysicalAddress = (void *) logicalAddress;
3876+ }
3877+ else
3878+ {
3879+ status = BSP_vme2local_adrs(EPICStovxWorksAddrType[addrType],
3880+ logicalAddress, (unsigned long *)ppPhysicalAddress);
3881+ if (status) {
3882+ return S_dev_addrMapFail;
3883+ }
3884+ }
3885+
3886+ return 0;
3887+}
3888+
3889+/*
3890+ * a bus error safe "wordSize" read at the specified address which returns
3891+ * unsuccessful status if the device isnt present
3892+ */
3893+rtems_status_code bspExtMemProbe(void *addr, int write, int size, void *pval);
3894+static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue)
3895+{
3896+ long status;
3897+
3898+ /*
3899+ * this global variable exists in the nivxi library
3900+ */
3901+ status = bspExtMemProbe ((void*)ptr, 0/*read*/, wordSize, pValue);
3902+ if (status!=RTEMS_SUCCESSFUL) {
3903+ return S_dev_noDevice;
3904+ }
3905+
3906+ return 0;
3907+}
3908+
3909+/*
3910+ * a bus error safe "wordSize" write at the specified address which returns
3911+ * unsuccessful status if the device isnt present
3912+ */
3913+static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue)
3914+{
3915+ long status;
3916+
3917+ /*
3918+ * this global variable exists in the nivxi library
3919+ */
3920+ status = bspExtMemProbe ((void*)ptr, 1/*write*/, wordSize, (void*)pValue);
3921+ if (status!=RTEMS_SUCCESSFUL) {
3922+ return S_dev_noDevice;
3923+ }
3924+
3925+ return 0;
3926+}
3927+
3928+/*
3929+ * isrFetch()
3930+ */
3931+static myISR *isrFetch(unsigned vectorNumber, void **parg)
3932+{
3933+ /*
3934+ * fetch the handler or C stub attached at this vector
3935+ */
3936+ return (myISR *) BSP_getVME_isr(vectorNumber,parg);
3937+}
3938+
3939+/*
3940+ * determine if a VME interrupt vector is in use
3941+ */
3942+static int rtemsDevInterruptInUseVME (unsigned vectorNumber)
3943+{
3944+ int i;
3945+ myISR *psub;
3946+ void *arg;
3947+
3948+ psub = isrFetch (vectorNumber,&arg);
3949+
3950+ if (!psub)
3951+ return FALSE;
3952+
3953+ /*
3954+ * its a C routine. Does it match a default handler?
3955+ */
3956+ for (i=0; i<NELEMENTS(defaultHandlerAddr); i++) {
3957+ if (defaultHandlerAddr[i] == psub) {
3958+ return FALSE;
3959+ }
3960+ }
3961+
3962+ return TRUE;
3963+}
3964+
3965+
3966+/*
3967+ * unsolicitedHandlerEPICS()
3968+ * what gets called if they disconnect from an
3969+ * interrupt and an interrupt arrives on the
3970+ * disconnected vector
3971+ *
3972+ * NOTE: RTEMS may pass additional arguments - hope
3973+ * this doesn't disturb this handler...
3974+ *
3975+ * A cleaner way would be having a OS dependent
3976+ * macro to declare handler prototypes...
3977+ *
3978+ */
3979+static void unsolicitedHandlerEPICS(int vectorNumber)
3980+{
3981+ /*
3982+ * call epicInterruptContextMessage()
3983+ * and not errMessage()
3984+ * so we are certain that printf()
3985+ * does not get called at interrupt level
3986+ *
3987+ * NOTE: current RTEMS implementation only
3988+ * allows a static string to be passed
3989+ */
3990+ epicsInterruptContextMessage(
3991+ "Interrupt to EPICS disconnected vector"
3992+ );
3993+}
3994+
3995+#endif /* defined(__PPC__) && defined(mpc750) */
3996+
3997+/*
3998+ * Some vxWorks convenience routines
3999+ */
4000+void
4001+bcopyLongs(char *source, char *destination, int nlongs)
4002+{
4003+ const long *s = (long *)source;
4004+ long *d = (long *)destination;
4005+ while(nlongs--)
4006+ *d++ = *s++;
4007+}
4008
4009=== removed file 'src/libCom/osi/os/cygwin32/devLibOSD.c'
4010--- src/libCom/osi/os/cygwin32/devLibOSD.c 2009-06-15 16:10:07 +0000
4011+++ src/libCom/osi/os/cygwin32/devLibOSD.c 1970-01-01 00:00:00 +0000
4012@@ -1,15 +0,0 @@
4013-/*************************************************************************\
4014-* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
4015-* National Laboratory.
4016-* EPICS BASE is distributed subject to a Software License Agreement found
4017-* in file LICENSE that is included with this distribution.
4018-\*************************************************************************/
4019-
4020-/* $Id$ */
4021-
4022-#include <stdlib.h>
4023-
4024-#define epicsExportSharedSymbols
4025-#include "devLib.h"
4026-
4027-epicsShareDef devLibVirtualOS *pdevLibVirtualOS = NULL;
4028
4029=== added file 'src/libCom/osi/os/cygwin32/devLibVMEOSD.c'
4030--- src/libCom/osi/os/cygwin32/devLibVMEOSD.c 1970-01-01 00:00:00 +0000
4031+++ src/libCom/osi/os/cygwin32/devLibVMEOSD.c 2010-05-28 11:06:32 +0000
4032@@ -0,0 +1,15 @@
4033+/*************************************************************************\
4034+* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
4035+* National Laboratory.
4036+* EPICS BASE is distributed subject to a Software License Agreement found
4037+* in file LICENSE that is included with this distribution.
4038+\*************************************************************************/
4039+
4040+/* $Id$ */
4041+
4042+#include <stdlib.h>
4043+
4044+#define epicsExportSharedSymbols
4045+#include "devLibVME.h"
4046+
4047+epicsShareDef devLibVME *pdevLibVME = NULL;
4048
4049=== removed file 'src/libCom/osi/os/default/devLibOSD.c'
4050--- src/libCom/osi/os/default/devLibOSD.c 2006-02-17 22:51:26 +0000
4051+++ src/libCom/osi/os/default/devLibOSD.c 1970-01-01 00:00:00 +0000
4052@@ -1,17 +0,0 @@
4053-/*************************************************************************\
4054-* Copyright (c) 2006 The University of Chicago, as Operator of Argonne
4055-* National Laboratory.
4056-* EPICS BASE Versions 3.13.7
4057-* and higher are distributed subject to a Software License Agreement found
4058-* in file LICENSE that is included with this distribution.
4059-\*************************************************************************/
4060-
4061-/* $Id$ */
4062-
4063-#include <stdlib.h>
4064-
4065-#include "devLib.h"
4066-
4067-/* This file must contain no definitions other than the following: */
4068-
4069-devLibVirtualOS *pdevLibVirtualOS;
4070
4071=== added file 'src/libCom/osi/os/default/devLibVMEOSD.c'
4072--- src/libCom/osi/os/default/devLibVMEOSD.c 1970-01-01 00:00:00 +0000
4073+++ src/libCom/osi/os/default/devLibVMEOSD.c 2010-05-28 11:06:32 +0000
4074@@ -0,0 +1,17 @@
4075+/*************************************************************************\
4076+* Copyright (c) 2006 The University of Chicago, as Operator of Argonne
4077+* National Laboratory.
4078+* EPICS BASE Versions 3.13.7
4079+* and higher are distributed subject to a Software License Agreement found
4080+* in file LICENSE that is included with this distribution.
4081+\*************************************************************************/
4082+
4083+/* $Id$ */
4084+
4085+#include <stdlib.h>
4086+
4087+#include "devLibVME.h"
4088+
4089+/* This file must contain no definitions other than the following: */
4090+
4091+devLibVME *pdevLibVME;
4092
4093=== removed file 'src/libCom/osi/os/vxWorks/devLibOSD.c'
4094--- src/libCom/osi/os/vxWorks/devLibOSD.c 2009-07-09 16:37:24 +0000
4095+++ src/libCom/osi/os/vxWorks/devLibOSD.c 1970-01-01 00:00:00 +0000
4096@@ -1,486 +0,0 @@
4097-/*************************************************************************\
4098-* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
4099-* National Laboratory.
4100-* Copyright (c) 2002 The Regents of the University of California, as
4101-* Operator of Los Alamos National Laboratory.
4102-* EPICS BASE is distributed subject to a Software License Agreement found
4103-* in file LICENSE that is included with this distribution.
4104-\*************************************************************************/
4105-/*
4106- * $Id$
4107- *
4108- * Archictecture dependent support for common device driver resources
4109- *
4110- * Author: Jeff Hill
4111- * Date: 10-30-98
4112- */
4113-
4114-#include <stdlib.h>
4115-
4116-#include <vxWorks.h>
4117-#include <types.h>
4118-#include <iv.h>
4119-#include <vme.h>
4120-#include <sysLib.h>
4121-#include <memLib.h>
4122-#include <intLib.h>
4123-#include <logLib.h>
4124-#include <vxLib.h>
4125-
4126-#include "epicsFindSymbol.h"
4127-#include "devLib.h"
4128-#include "errlog.h"
4129-
4130-typedef void myISR (void *pParam);
4131-
4132-#if CPU_FAMILY != PPC
4133-/*
4134- * A list of the names of the unexpected interrupt handlers
4135- * ( some of these are provided by wrs )
4136- */
4137-static char *defaultHandlerNames[] = {
4138- "excStub",
4139- "excIntStub",
4140- "unsolicitedHandlerEPICS"};
4141-
4142-static myISR *defaultHandlerAddr[NELEMENTS(defaultHandlerNames)];
4143-#endif
4144-
4145-static myISR *isrFetch(unsigned vectorNumber);
4146-
4147-/*
4148- * this routine needs to be in the symbol table
4149- * for this code to work correctly
4150- */
4151-void unsolicitedHandlerEPICS(int vectorNumber);
4152-
4153-/*
4154- * this is in veclist.c
4155- */
4156-int cISRTest(void (*)(), void (**)(), void **);
4157-
4158-/*
4159- * Make sure that the CR/CSR addressing mode is defined.
4160- * (it may not be in older versions of vxWorks)
4161- */
4162-#ifndef VME_AM_CSR
4163-# define VME_AM_CSR (0x2f)
4164-#endif
4165-
4166-/*
4167- * we use a translation between an EPICS encoding
4168- * and a vxWorks encoding here
4169- * to reduce dependency of drivers on vxWorks
4170- *
4171- * we assume that the BSP are configured to use these
4172- * address modes by default
4173- */
4174-
4175-#define EPICSAddrTypeNoConvert -1
4176-
4177-int EPICStovxWorksAddrType[]
4178- = {
4179- VME_AM_SUP_SHORT_IO,
4180- VME_AM_STD_SUP_DATA,
4181- VME_AM_EXT_SUP_DATA,
4182- EPICSAddrTypeNoConvert,
4183- VME_AM_CSR
4184- };
4185-
4186-#if CPU_FAMILY != PPC
4187-static void initHandlerAddrList(void);
4188-#endif
4189-
4190-/*
4191- * maps logical address to physical address, but does not detect
4192- * two device drivers that are using the same address range
4193- */
4194-static long vxDevMapAddr (epicsAddressType addrType, unsigned options,
4195- size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
4196-
4197-/*
4198- * a bus error safe "wordSize" read at the specified address which returns
4199- * unsuccessful status if the device isnt present
4200- */
4201-static long vxDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue);
4202-
4203-/*
4204- * a bus error safe "wordSize" write at the specified address which returns
4205- * unsuccessful status if the device isnt present
4206- */
4207-static long vxDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue);
4208-
4209-static void *devA24Malloc(size_t size);
4210-static void devA24Free(void *pBlock);
4211-static long devInit(void) { return 0;}
4212-
4213-/*
4214- * used by dynamic bind in devLib.c
4215- */
4216-static devLibVirtualOS vxVirtualOS = {
4217- vxDevMapAddr, vxDevReadProbe, vxDevWriteProbe,
4218- devConnectInterruptVME, devDisconnectInterruptVME,
4219- devEnableInterruptLevelVME, devDisableInterruptLevelVME,
4220- devA24Malloc,devA24Free,devInit
4221-};
4222-devLibVirtualOS *pdevLibVirtualOS = &vxVirtualOS;
4223-
4224-/*
4225- * devConnectInterruptVME
4226- *
4227- * wrapper to minimize driver dependency on vxWorks
4228- */
4229-long devConnectInterruptVME (
4230- unsigned vectorNumber,
4231- void (*pFunction)(),
4232- void *parameter)
4233-{
4234- int status;
4235-
4236-
4237- if (devInterruptInUseVME(vectorNumber)) {
4238- return S_dev_vectorInUse;
4239- }
4240- status = intConnect(
4241- (void *)INUM_TO_IVEC(vectorNumber),
4242- pFunction,
4243- (int) parameter);
4244- if (status<0) {
4245- return S_dev_vecInstlFail;
4246- }
4247-
4248- return 0;
4249-}
4250-
4251-/*
4252- *
4253- * devDisconnectInterruptVME()
4254- *
4255- * wrapper to minimize driver dependency on vxWorks
4256- *
4257- * The parameter pFunction should be set to the C function pointer that
4258- * was connected. It is used as a key to prevent a driver from removing
4259- * an interrupt handler that was installed by another driver
4260- *
4261- */
4262-long devDisconnectInterruptVME (
4263- unsigned vectorNumber,
4264- void (*pFunction)()
4265-)
4266-{
4267- void (*psub)();
4268- int status;
4269-
4270-# if CPU_FAMILY == PPC
4271- return S_dev_vecInstlFail;
4272-# endif
4273-
4274- /*
4275- * If pFunction not connected to this vector
4276- * then they are probably disconnecting from the wrong vector
4277- */
4278- psub = isrFetch(vectorNumber);
4279- if(psub != pFunction){
4280- return S_dev_vectorNotInUse;
4281- }
4282-
4283- status = intConnect(
4284- (void *)INUM_TO_IVEC(vectorNumber),
4285- unsolicitedHandlerEPICS,
4286- (int) vectorNumber);
4287- if(status<0){
4288- return S_dev_vecInstlFail;
4289- }
4290-
4291- return 0;
4292-}
4293-
4294-/*
4295- * enable VME interrupt level
4296- */
4297-long devEnableInterruptLevelVME (unsigned level)
4298-{
4299-# if CPU_FAMILY != I80X86
4300- int s;
4301- s = sysIntEnable (level);
4302- if (s!=OK) {
4303- return S_dev_intEnFail;
4304- }
4305- return 0;
4306-# else
4307- return S_dev_intEnFail;
4308-# endif
4309-}
4310-
4311-/*
4312- * enable ISA interrupt level
4313- */
4314-long devEnableInterruptLevelISA (unsigned level)
4315-{
4316-# if CPU_FAMILY == I80X86
4317- int s;
4318- s = sysIntEnablePIC (level);
4319- if (s!=OK) {
4320- return S_dev_intEnFail;
4321- }
4322- return 0;
4323-# else
4324- return S_dev_intEnFail;
4325-# endif
4326-}
4327-
4328-/*
4329- * disable ISA interrupt level
4330- */
4331-long devDisableInterruptLevelISA (unsigned level)
4332-{
4333-# if CPU_FAMILY == I80X86
4334- int s;
4335- s = sysIntDisablePIC (level);
4336- if (s!=OK) {
4337- return S_dev_intEnFail;
4338- }
4339-# else
4340- return S_dev_intEnFail;
4341-# endif
4342-
4343- return 0;
4344-}
4345-
4346-/*
4347- * disable VME interrupt level
4348- */
4349-long devDisableInterruptLevelVME (unsigned level)
4350-{
4351-# if CPU_FAMILY != I80X86
4352- int s;
4353- s = sysIntDisable (level);
4354- if (s!=OK) {
4355- return S_dev_intDissFail;
4356- }
4357- return 0;
4358-# else
4359- return S_dev_intEnFail;
4360-# endif
4361-}
4362-
4363-/*
4364- * vxDevMapAddr ()
4365- */
4366-static long vxDevMapAddr (epicsAddressType addrType, unsigned options,
4367- size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress)
4368-{
4369- long status;
4370-
4371- if (ppPhysicalAddress==NULL) {
4372- return S_dev_badArgument;
4373- }
4374-
4375- if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert)
4376- {
4377- *ppPhysicalAddress = (void *) logicalAddress;
4378- }
4379- else
4380- {
4381- status = sysBusToLocalAdrs (EPICStovxWorksAddrType[addrType],
4382- (char *) logicalAddress, (char **)ppPhysicalAddress);
4383- if (status) {
4384- return S_dev_addrMapFail;
4385- }
4386- }
4387-
4388- return 0;
4389-}
4390-
4391-/*
4392- * a bus error safe "wordSize" read at the specified address which returns
4393- * unsuccessful status if the device isn't present
4394- */
4395-static long vxDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue)
4396-{
4397- long status;
4398-
4399- status = vxMemProbe ((char *)ptr, VX_READ, wordSize, (char *) pValue);
4400- if (status!=OK) {
4401- return S_dev_noDevice;
4402- }
4403-
4404- return 0;
4405-}
4406-
4407-/*
4408- * a bus error safe "wordSize" write at the specified address which returns
4409- * unsuccessful status if the device isn't present
4410- */
4411-static long vxDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue)
4412-{
4413- long status;
4414-
4415- status = vxMemProbe ((char *)ptr, VX_WRITE, wordSize, (char *) pValue);
4416- if (status!=OK) {
4417- return S_dev_noDevice;
4418- }
4419-
4420- return 0;
4421-}
4422-
4423-/*
4424- * isrFetch()
4425- */
4426-static myISR *isrFetch(unsigned vectorNumber)
4427-{
4428- myISR *psub;
4429- myISR *pCISR;
4430- void *pParam;
4431- int s;
4432-
4433- /*
4434- * fetch the handler or C stub attached at this vector
4435- */
4436- psub = (myISR *) intVecGet((FUNCPTR *)INUM_TO_IVEC(vectorNumber));
4437-
4438- if ( psub ) {
4439- /*
4440- * from libvxWorks/veclist.c
4441- *
4442- * checks to see if it is a C ISR
4443- * and if so finds the function pointer and
4444- * the parameter passed
4445- */
4446- s = cISRTest(psub, &pCISR, &pParam);
4447- if(!s){
4448- psub = pCISR;
4449- }
4450- }
4451-
4452- return psub;
4453-}
4454-
4455-/*
4456- * determine if a VME interrupt vector is in use
4457- */
4458-int devInterruptInUseVME (unsigned vectorNumber)
4459-{
4460-#if CPU_FAMILY == PPC
4461- return FALSE;
4462-#else
4463- {
4464- static int init;
4465- int i;
4466- myISR *psub;
4467-
4468- if (!init) {
4469- initHandlerAddrList();
4470- init = TRUE;
4471- }
4472-
4473- psub = isrFetch (vectorNumber);
4474-
4475- /*
4476- * its a C routine. Does it match a default handler?
4477- */
4478- for (i=0; i<NELEMENTS(defaultHandlerAddr); i++) {
4479- if (defaultHandlerAddr[i] == psub) {
4480- return FALSE;
4481- }
4482- }
4483- }
4484- return TRUE;
4485-# endif
4486-}
4487-
4488-
4489-/*
4490- * unsolicitedHandlerEPICS()
4491- * what gets called if they disconnect from an
4492- * interrupt and an interrupt arrives on the
4493- * disconnected vector
4494- *
4495- */
4496-void unsolicitedHandlerEPICS(int vectorNumber)
4497-{
4498- /*
4499- * call logMsg() and not errMessage()
4500- * so we are certain that printf()
4501- * does not get called at interrupt level
4502- */
4503- logMsg(
4504- "%s: line=%d: Interrupt to EPICS disconnected vector = 0X %X",
4505- (int)__FILE__,
4506- __LINE__,
4507- vectorNumber,
4508- 0,
4509- 0,
4510- 0);
4511-}
4512-
4513-#if CPU_FAMILY != PPC
4514-/*
4515- *
4516- * initHandlerAddrList()
4517- * init list of interrupt handlers to ignore
4518- *
4519- */
4520-static
4521-void initHandlerAddrList(void)
4522-{
4523- int i;
4524-
4525- for (i=0; i<NELEMENTS(defaultHandlerNames); i++) {
4526- defaultHandlerAddr[i] = epicsFindSymbol(defaultHandlerNames[i]);
4527- if(!defaultHandlerAddr[i]) {
4528- errPrintf(
4529- S_dev_internal,
4530- __FILE__,
4531- __LINE__,
4532- "initHandlerAddrList() %s not in sym table",
4533- defaultHandlerNames[i]);
4534- }
4535- }
4536-}
4537-#endif
4538-
4539-/******************************************************************************
4540- *
4541- * Routines to use to allocate and free memory present in the A24 region.
4542- *
4543- ******************************************************************************/
4544-
4545-static void * (*A24MallocFunc)(size_t) = NULL;
4546-static void (*A24FreeFunc)(void *) = NULL;
4547-
4548-static void *devA24Malloc(size_t size)
4549-{
4550- static int UsingBSP = 0;
4551- void *ret;
4552-
4553- if (A24MallocFunc == NULL)
4554- {
4555- /* See if the sysA24Malloc() function is present. */
4556- A24MallocFunc = epicsFindSymbol("sysA24Malloc");
4557- if(!A24MallocFunc) {
4558- A24MallocFunc = malloc;
4559- A24FreeFunc = free;
4560- } else {
4561- A24FreeFunc = epicsFindSymbol("sysA24Free");
4562- if(!A24FreeFunc) {
4563- /* That's strange... we have malloc, but no free! */
4564- A24MallocFunc = malloc;
4565- A24FreeFunc = free;
4566- } else {
4567- UsingBSP = 1;
4568- }
4569- }
4570- }
4571- ret = A24MallocFunc(size);
4572-
4573- if ((ret == NULL) && (UsingBSP))
4574- errMessage(S_dev_noMemory, "devLibA24Malloc ran out of A24 memory, try sysA24MapRam(size)");
4575-
4576- return(ret);
4577-}
4578-
4579-static void devA24Free(void *pBlock)
4580-{
4581- A24FreeFunc(pBlock);
4582-}
4583
4584=== added file 'src/libCom/osi/os/vxWorks/devLibVMEOSD.c'
4585--- src/libCom/osi/os/vxWorks/devLibVMEOSD.c 1970-01-01 00:00:00 +0000
4586+++ src/libCom/osi/os/vxWorks/devLibVMEOSD.c 2010-05-28 11:06:32 +0000
4587@@ -0,0 +1,502 @@
4588+/*************************************************************************\
4589+* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
4590+* National Laboratory.
4591+* Copyright (c) 2002 The Regents of the University of California, as
4592+* Operator of Los Alamos National Laboratory.
4593+* EPICS BASE is distributed subject to a Software License Agreement found
4594+* in file LICENSE that is included with this distribution.
4595+\*************************************************************************/
4596+/*
4597+ * $Id$
4598+ *
4599+ * Archictecture dependent support for common device driver resources
4600+ *
4601+ * Author: Jeff Hill
4602+ * Date: 10-30-98
4603+ */
4604+
4605+#include <stdlib.h>
4606+
4607+#include <vxWorks.h>
4608+#include <types.h>
4609+#include <iv.h>
4610+#include <vme.h>
4611+#include <sysLib.h>
4612+#include <memLib.h>
4613+#include <intLib.h>
4614+#include <logLib.h>
4615+#include <vxLib.h>
4616+
4617+#include "epicsFindSymbol.h"
4618+#include "devLibVME.h"
4619+#include "errlog.h"
4620+
4621+typedef void myISR (void *pParam);
4622+
4623+#if CPU_FAMILY != PPC
4624+/*
4625+ * A list of the names of the unexpected interrupt handlers
4626+ * ( some of these are provided by wrs )
4627+ */
4628+static char *defaultHandlerNames[] = {
4629+ "excStub",
4630+ "excIntStub",
4631+ "unsolicitedHandlerEPICS"};
4632+
4633+static myISR *defaultHandlerAddr[NELEMENTS(defaultHandlerNames)];
4634+#endif
4635+
4636+static myISR *isrFetch(unsigned vectorNumber);
4637+
4638+/*
4639+ * this routine needs to be in the symbol table
4640+ * for this code to work correctly
4641+ */
4642+static void unsolicitedHandlerEPICS(int vectorNumber);
4643+
4644+/*
4645+ * this is in veclist.c
4646+ */
4647+int cISRTest(void (*)(), void (**)(), void **);
4648+
4649+/*
4650+ * Make sure that the CR/CSR addressing mode is defined.
4651+ * (it may not be in older versions of vxWorks)
4652+ */
4653+#ifndef VME_AM_CSR
4654+# define VME_AM_CSR (0x2f)
4655+#endif
4656+
4657+/*
4658+ * we use a translation between an EPICS encoding
4659+ * and a vxWorks encoding here
4660+ * to reduce dependency of drivers on vxWorks
4661+ *
4662+ * we assume that the BSP are configured to use these
4663+ * address modes by default
4664+ */
4665+
4666+#define EPICSAddrTypeNoConvert -1
4667+
4668+int EPICStovxWorksAddrType[]
4669+ = {
4670+ VME_AM_SUP_SHORT_IO,
4671+ VME_AM_STD_SUP_DATA,
4672+ VME_AM_EXT_SUP_DATA,
4673+ EPICSAddrTypeNoConvert,
4674+ VME_AM_CSR
4675+ };
4676+
4677+#if CPU_FAMILY != PPC
4678+static void initHandlerAddrList(void);
4679+#endif
4680+
4681+/*
4682+ * maps logical address to physical address, but does not detect
4683+ * two device drivers that are using the same address range
4684+ */
4685+static long vxDevMapAddr (epicsAddressType addrType, unsigned options,
4686+ size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
4687+
4688+/*
4689+ * a bus error safe "wordSize" read at the specified address which returns
4690+ * unsuccessful status if the device isnt present
4691+ */
4692+static long vxDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue);
4693+
4694+/*
4695+ * a bus error safe "wordSize" write at the specified address which returns
4696+ * unsuccessful status if the device isnt present
4697+ */
4698+static long vxDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue);
4699+
4700+static void *devA24Malloc(size_t size);
4701+static void devA24Free(void *pBlock);
4702+static long devInit(void) { return 0;}
4703+
4704+static long vxDevConnectInterruptVME (
4705+ unsigned vectorNumber,
4706+ void (*pFunction)(),
4707+ void *parameter);
4708+
4709+static long vxDevDisconnectInterruptVME (
4710+ unsigned vectorNumber,
4711+ void (*pFunction)()
4712+);
4713+
4714+static long vxDevEnableInterruptLevelVME (unsigned level);
4715+
4716+static long vxDevDisableInterruptLevelVME (unsigned level);
4717+
4718+static int vxDevInterruptInUseVME (unsigned vectorNumber);
4719+
4720+/*
4721+ * used by dynamic bind in devLib.c
4722+ */
4723+static devLibVME vxVirtualOS = {
4724+ vxDevMapAddr, vxDevReadProbe, vxDevWriteProbe,
4725+ vxDevConnectInterruptVME, vxDevDisconnectInterruptVME,
4726+ vxDevEnableInterruptLevelVME, vxDevDisableInterruptLevelVME,
4727+ devA24Malloc,devA24Free,devInit,vxDevInterruptInUseVME
4728+};
4729+devLibVME *pdevLibVME = &vxVirtualOS;
4730+
4731+/*
4732+ * devConnectInterruptVME
4733+ *
4734+ * wrapper to minimize driver dependency on vxWorks
4735+ */
4736+static long vxDevConnectInterruptVME (
4737+ unsigned vectorNumber,
4738+ void (*pFunction)(),
4739+ void *parameter)
4740+{
4741+ int status;
4742+
4743+
4744+ if (devInterruptInUseVME(vectorNumber)) {
4745+ return S_dev_vectorInUse;
4746+ }
4747+ status = intConnect(
4748+ (void *)INUM_TO_IVEC(vectorNumber),
4749+ pFunction,
4750+ (int) parameter);
4751+ if (status<0) {
4752+ return S_dev_vecInstlFail;
4753+ }
4754+
4755+ return 0;
4756+}
4757+
4758+/*
4759+ *
4760+ * vxDevDisconnectInterruptVME()
4761+ *
4762+ * wrapper to minimize driver dependency on vxWorks
4763+ *
4764+ * The parameter pFunction should be set to the C function pointer that
4765+ * was connected. It is used as a key to prevent a driver from removing
4766+ * an interrupt handler that was installed by another driver
4767+ *
4768+ */
4769+static long vxDevDisconnectInterruptVME (
4770+ unsigned vectorNumber,
4771+ void (*pFunction)()
4772+)
4773+{
4774+ void (*psub)();
4775+ int status;
4776+
4777+# if CPU_FAMILY == PPC
4778+ return S_dev_vecInstlFail;
4779+# endif
4780+
4781+ /*
4782+ * If pFunction not connected to this vector
4783+ * then they are probably disconnecting from the wrong vector
4784+ */
4785+ psub = isrFetch(vectorNumber);
4786+ if(psub != pFunction){
4787+ return S_dev_vectorNotInUse;
4788+ }
4789+
4790+ status = intConnect(
4791+ (void *)INUM_TO_IVEC(vectorNumber),
4792+ unsolicitedHandlerEPICS,
4793+ (int) vectorNumber);
4794+ if(status<0){
4795+ return S_dev_vecInstlFail;
4796+ }
4797+
4798+ return 0;
4799+}
4800+
4801+/*
4802+ * enable VME interrupt level
4803+ */
4804+static long vxDevEnableInterruptLevelVME (unsigned level)
4805+{
4806+# if CPU_FAMILY != I80X86
4807+ int s;
4808+ s = sysIntEnable (level);
4809+ if (s!=OK) {
4810+ return S_dev_intEnFail;
4811+ }
4812+ return 0;
4813+# else
4814+ return S_dev_intEnFail;
4815+# endif
4816+}
4817+
4818+/*
4819+ * enable ISA interrupt level
4820+ */
4821+long devEnableInterruptLevelISA (unsigned level)
4822+{
4823+# if CPU_FAMILY == I80X86
4824+ int s;
4825+ s = sysIntEnablePIC (level);
4826+ if (s!=OK) {
4827+ return S_dev_intEnFail;
4828+ }
4829+ return 0;
4830+# else
4831+ return S_dev_intEnFail;
4832+# endif
4833+}
4834+
4835+/*
4836+ * disable ISA interrupt level
4837+ */
4838+long devDisableInterruptLevelISA (unsigned level)
4839+{
4840+# if CPU_FAMILY == I80X86
4841+ int s;
4842+ s = sysIntDisablePIC (level);
4843+ if (s!=OK) {
4844+ return S_dev_intEnFail;
4845+ }
4846+# else
4847+ return S_dev_intEnFail;
4848+# endif
4849+
4850+ return 0;
4851+}
4852+
4853+/*
4854+ * disable VME interrupt level
4855+ */
4856+static long vxDevDisableInterruptLevelVME (unsigned level)
4857+{
4858+# if CPU_FAMILY != I80X86
4859+ int s;
4860+ s = sysIntDisable (level);
4861+ if (s!=OK) {
4862+ return S_dev_intDissFail;
4863+ }
4864+ return 0;
4865+# else
4866+ return S_dev_intEnFail;
4867+# endif
4868+}
4869+
4870+/*
4871+ * vxDevMapAddr ()
4872+ */
4873+static long vxDevMapAddr (epicsAddressType addrType, unsigned options,
4874+ size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress)
4875+{
4876+ long status;
4877+
4878+ if (ppPhysicalAddress==NULL) {
4879+ return S_dev_badArgument;
4880+ }
4881+
4882+ if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert)
4883+ {
4884+ *ppPhysicalAddress = (void *) logicalAddress;
4885+ }
4886+ else
4887+ {
4888+ status = sysBusToLocalAdrs (EPICStovxWorksAddrType[addrType],
4889+ (char *) logicalAddress, (char **)ppPhysicalAddress);
4890+ if (status) {
4891+ return S_dev_addrMapFail;
4892+ }
4893+ }
4894+
4895+ return 0;
4896+}
4897+
4898+/*
4899+ * a bus error safe "wordSize" read at the specified address which returns
4900+ * unsuccessful status if the device isn't present
4901+ */
4902+static long vxDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue)
4903+{
4904+ long status;
4905+
4906+ status = vxMemProbe ((char *)ptr, VX_READ, wordSize, (char *) pValue);
4907+ if (status!=OK) {
4908+ return S_dev_noDevice;
4909+ }
4910+
4911+ return 0;
4912+}
4913+
4914+/*
4915+ * a bus error safe "wordSize" write at the specified address which returns
4916+ * unsuccessful status if the device isn't present
4917+ */
4918+static long vxDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue)
4919+{
4920+ long status;
4921+
4922+ status = vxMemProbe ((char *)ptr, VX_WRITE, wordSize, (char *) pValue);
4923+ if (status!=OK) {
4924+ return S_dev_noDevice;
4925+ }
4926+
4927+ return 0;
4928+}
4929+
4930+/*
4931+ * isrFetch()
4932+ */
4933+static myISR *isrFetch(unsigned vectorNumber)
4934+{
4935+ myISR *psub;
4936+ myISR *pCISR;
4937+ void *pParam;
4938+ int s;
4939+
4940+ /*
4941+ * fetch the handler or C stub attached at this vector
4942+ */
4943+ psub = (myISR *) intVecGet((FUNCPTR *)INUM_TO_IVEC(vectorNumber));
4944+
4945+ if ( psub ) {
4946+ /*
4947+ * from libvxWorks/veclist.c
4948+ *
4949+ * checks to see if it is a C ISR
4950+ * and if so finds the function pointer and
4951+ * the parameter passed
4952+ */
4953+ s = cISRTest(psub, &pCISR, &pParam);
4954+ if(!s){
4955+ psub = pCISR;
4956+ }
4957+ }
4958+
4959+ return psub;
4960+}
4961+
4962+/*
4963+ * determine if a VME interrupt vector is in use
4964+ */
4965+static int vxDevInterruptInUseVME (unsigned vectorNumber)
4966+{
4967+#if CPU_FAMILY == PPC
4968+ return FALSE;
4969+#else
4970+ {
4971+ static int init;
4972+ int i;
4973+ myISR *psub;
4974+
4975+ if (!init) {
4976+ initHandlerAddrList();
4977+ init = TRUE;
4978+ }
4979+
4980+ psub = isrFetch (vectorNumber);
4981+
4982+ /*
4983+ * its a C routine. Does it match a default handler?
4984+ */
4985+ for (i=0; i<NELEMENTS(defaultHandlerAddr); i++) {
4986+ if (defaultHandlerAddr[i] == psub) {
4987+ return FALSE;
4988+ }
4989+ }
4990+ }
4991+ return TRUE;
4992+# endif
4993+}
4994+
4995+
4996+/*
4997+ * unsolicitedHandlerEPICS()
4998+ * what gets called if they disconnect from an
4999+ * interrupt and an interrupt arrives on the
5000+ * disconnected vector
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches