Skip to content

Commit f05486a

Browse files
authored
Merge cc2af2e into d95da30
2 parents d95da30 + cc2af2e commit f05486a

File tree

4 files changed

+110
-43
lines changed

4 files changed

+110
-43
lines changed

configure/CONFIG_DEVLIB2_VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
DEVLIB2_MAJOR_VERSION = 2
2-
DEVLIB2_MINOR_VERSION = 12
2+
DEVLIB2_MINOR_VERSION = 13

pciApp/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ DBD += epicspci.dbd
2020

2121
INC += devLibPCI.h
2222
INC += devLibPCIImpl.h
23+
INC += devLibPCIOSD.h
2324

2425
epicspci_SRCS += devLibPCI.c
2526
epicspci_SRCS += devLibPCIStrings.c
@@ -37,4 +38,3 @@ epicspci_LIBS += Com
3738
include $(TOP)/configure/RULES
3839
#----------------------------------------
3940
# ADD RULES AFTER THIS LINE
40-

pciApp/os/Linux/devLibPCIOSD.c

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@
2222
#include <errlog.h>
2323
#include <epicsString.h>
2424
#include <epicsThread.h>
25-
#include <epicsMutex.h>
2625
#include <epicsEvent.h>
2726
#include <epicsInterrupt.h>
2827
#include <compilerDependencies.h>
2928

30-
31-
#include "devLibPCIImpl.h"
29+
#include "devLibPCIOSD.h"
3230

3331
/**@file devLibPCIOSD.c
3432
* @brief Userspace PCI access in Linux
@@ -82,33 +80,6 @@
8280
*
8381
* Access after init is guarded by devLock
8482
*/
85-
struct osdPCIDevice {
86-
epicsPCIDevice dev; /* "public" data */
87-
88-
/* result of mmap(), add offset before passing to user */
89-
volatile void *base[PCIBARCOUNT];
90-
/* offset from start of page to start of BAR */
91-
epicsUInt32 offset[PCIBARCOUNT];
92-
/* BAR length (w/o offset) */
93-
epicsUInt32 len[PCIBARCOUNT];
94-
volatile void *erom;
95-
epicsUInt32 eromlen;
96-
97-
epicsUInt32 displayBAR[PCIBARCOUNT]; /* Raw PCI address */
98-
epicsUInt32 displayErom;
99-
100-
int fd; /* /dev/uio# */
101-
int cfd; /* config-space descriptor */
102-
int rfd[PCIBARCOUNT];
103-
int cmode; /* config-space mode */
104-
105-
epicsMutexId devLock; /* guard access to isrs list */
106-
107-
ELLNODE node;
108-
109-
ELLLIST isrs; /* contains struct osdISR */
110-
};
111-
typedef struct osdPCIDevice osdPCIDevice;
11283

11384
#define dev2osd(dev) CONTAINER(dev, osdPCIDevice, dev)
11485

@@ -507,7 +478,7 @@ int linuxDevPCIInit(void)
507478
/* Read BAR info */
508479

509480
/* Base address */
510-
481+
511482
filename = allocPrintf(BUSBASE "resource",
512483
osd->dev.domain, osd->dev.bus, osd->dev.device, osd->dev.function);
513484
if (!filename) {
@@ -548,10 +519,10 @@ int linuxDevPCIInit(void)
548519

549520
osd->displayErom = start;
550521
osd->eromlen = (start || stop ) ? (stop - start + 1) : 0;
551-
522+
552523
fclose(file);
553524
free(filename);
554-
525+
555526
/* driver name */
556527
filename = allocPrintf(BUSBASE "driver",
557528
osd->dev.domain, osd->dev.bus, osd->dev.device, osd->dev.function);
@@ -922,6 +893,28 @@ int linuxDevPCIConnectInterrupt(
922893
return ret;
923894
}
924895

896+
static int reopen_uio(struct osdPCIDevice *osd)
897+
{
898+
int uio = find_uio_number(osd);
899+
if (uio < 0)
900+
return -1;
901+
902+
char *devname = allocPrintf("/dev/uio%u", uio);
903+
if (!devname)
904+
return -1;
905+
906+
int newfd = open(devname, O_RDWR);
907+
free(devname);
908+
if (newfd < 0)
909+
return -1;
910+
911+
if (osd->fd != -1)
912+
close(osd->fd);
913+
914+
osd->fd = newfd;
915+
return 0;
916+
}
917+
925918
static
926919
void isrThread(void* arg)
927920
{
@@ -959,18 +952,36 @@ void isrThread(void* arg)
959952
epicsInterruptUnlock(isrflag);
960953
}
961954

962-
ret=read(osd->fd, &event, sizeof(event));
963-
if (ret==-1) {
964-
switch(errno) {
955+
ret = read(osd->fd, &event, sizeof(event));
956+
if (ret == -1) {
957+
switch (errno) {
965958
case EINTR: /* interrupted by a signal */
966959
break;
960+
961+
case EIO:
962+
case EINVAL:
963+
case ENODEV:
964+
errlogPrintf("isrThread '%s': Device removed or UIO invalid (errno=%d: %s)\n", name, errno, strerror(errno));
965+
966+
epicsMutexMustLock(osd->devLock);
967+
if (reopen_uio(osd) == 0) {
968+
errlogPrintf("isrThread '%s': Successfully reopened UIO device\n", name);
969+
if (osd->onHotSwapHook) osd->onHotSwapHook(osd);
970+
} else {
971+
errlogPrintf("isrThread '%s': UIO reopen failed. Will retry.\n", name);
972+
}
973+
epicsMutexUnlock(osd->devLock);
974+
epicsThreadSleep(1);
975+
continue;
976+
967977
default:
968-
errlogPrintf("isrThread '%s' read error %d\n",
969-
name,errno);
970-
epicsThreadSleep(0.5);
978+
errlogPrintf("isrThread '%s': read error %d (%s)\n", name, errno, strerror(errno));
979+
epicsThreadSleep(1);
971980
}
972-
} else
973-
interrupted=1;
981+
} else {
982+
interrupted = 1;
983+
}
984+
974985

975986
if (next!=event && next!=0) {
976987
errlogPrintf("isrThread '%s' missed %d events\n",

pciApp/os/Linux/devLibPCIOSD.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*************************************************************************\
2+
* Copyright (c) 2010 Brookhaven Science Associates, as Operator of
3+
* Brookhaven National Laboratory.
4+
* devLib2 is distributed subject to a Software License Agreement found
5+
* in file LICENSE that is included with this distribution.
6+
\*************************************************************************/
7+
8+
#ifndef DEVLIBPCIOSD_H_INC
9+
#define DEVLIBPCIOSD_H_INC
10+
11+
#include <epicsMutex.h>
12+
13+
#include "devLibPCIImpl.h"
14+
15+
#ifdef __cplusplus
16+
extern "C"
17+
{
18+
#endif
19+
20+
struct osdPCIDevice
21+
{
22+
epicsPCIDevice dev; /* "public" data */
23+
24+
/* result of mmap(), add offset before passing to user */
25+
volatile void* base[PCIBARCOUNT];
26+
/* offset from start of page to start of BAR */
27+
epicsUInt32 offset[PCIBARCOUNT];
28+
/* BAR length (w/o offset) */
29+
epicsUInt32 len[PCIBARCOUNT];
30+
volatile void* erom;
31+
epicsUInt32 eromlen;
32+
33+
epicsUInt32 displayBAR[PCIBARCOUNT]; /* Raw PCI address */
34+
epicsUInt32 displayErom;
35+
36+
int fd; /* /dev/uio# */
37+
int cfd; /* config-space descriptor */
38+
int rfd[PCIBARCOUNT];
39+
int cmode; /* config-space mode */
40+
41+
epicsMutexId devLock; /* guard access to isrs list */
42+
43+
/* Optional callback invoked on PCI device hot-swap.*/
44+
void (*onHotSwapHook)(struct osdPCIDevice*);
45+
46+
ELLNODE node;
47+
48+
ELLLIST isrs; /* contains struct osdISR */
49+
};
50+
typedef struct osdPCIDevice osdPCIDevice;
51+
52+
#ifdef __cplusplus
53+
}
54+
#endif
55+
56+
#endif /* DEVLIBPCIOSD_H_INC */

0 commit comments

Comments
 (0)