[LinuxPPS] [PATCH] time_pps_findpath()
Rodolfo Giometti
giometti at linux.it
Mon Jun 19 22:25:35 CEST 2006
Hi,
here a patch to add support for new function time_pps_findpath().
You may also find it on GITWeb as branch "dev_time_pps_findpath".
Please refere to testing file "ppstest.c" to know how to use the new
function. However the patch for NTPD driver should look as follow:
+#ifdef PPS_HAVE_FINDPATH
+ /* Get the PPS source's real name */
+ fd = readlink(link, path, STRING_LEN-1);
+ if (fd <= 0) {
+ msyslog(LOG_ERR, "refclock: PPS source \"%s\" is not a valid link", PPS_DEVI\CE);
+ return (1);
+ }
+ path[fd] = '\0';
+
+ /* Try to find the source */
+ fd = time_pps_findpath(path, STRING_LEN, id, STRING_LEN);
+ if (fd < 0) {
+ msyslog(LOG_ERR, "refclock: cannot find PPS source \"%s\" in the system", PPS_DEVICE);
+ return (1);
+ }
+ msyslog(LOG_INFO, "refclock: found PPS source \"%s\" at id #%d on \"%s\"", PPS_DEVICE, fd, id);
+#endif /* PPS_HAVE_FINDPATH */
+
+
if (time_pps_create(fd, &pps_handle) < 0) {
- pps_handle = 0;
msyslog(LOG_ERR,
"refclock: time_pps_create failed: %m");
}
Define PPS_DEVICE may be init as follow:
#define PPS_DEVICE "/dev/pps0"
In this manner we can surely address the right PPS device as show below:
giometti at jeeg:~/linuxpps$ cat /proc/pps/sources
id mode echo name path
---- ------ ---- ---------------- ----------------
00 1151 yes ktimer
01 1133 no pps_8250_0 /dev/ttyS0
02 1133 no pps_8250_1 /dev/ttyS1
03 1133 no pps_8250_2 /dev/ttyS2
04 1133 no pps_8250_3 /dev/ttyS3
giometti at jeeg:~/linuxpps/test$ sudo ln -sf /dev/ttyS1 /dev/gps0
giometti at jeeg:~/linuxpps/test$ sudo ./ppstest /dev/gps0
found PPS source #2 "pps_8250_1" on "/dev/ttyS1"
giometti at jeeg:~/linuxpps/test$ sudo ln -sf ktimer /dev/gps0
giometti at jeeg:~/linuxpps/test$ sudo ./ppstest /dev/gps0
found PPS source #0 "ktimer" on ""
Note that sources without a "path" can be addressed by "name".
Please, let me know what are think about that.
Ciao,
Rodolfo
--
GNU/Linux Solutions e-mail: giometti at enneenne.com
Linux Device Driver giometti at gnudd.com
Embedded Systems giometti at linux.it
UNIX programming phone: +39 349 2432127
-------------- next part --------------
diff --git a/drivers/pps/clients/ktimer.c b/drivers/pps/clients/ktimer.c
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c
index f9ff4c6..2539044 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -58,6 +58,24 @@ static inline int linuxpps_find_source(i
return i;
}
+static inline int linuxpps_find_path(char *path)
+{
+ int i;
+
+ for (i = 0; i < LINUXPPS_MAX_SOURCES; i++)
+ if (linuxpps_is_allocated(i) &&
+ (strncmp(linuxpps_source[i].info->path, path,
+ LINUXPPS_MAX_NAME_LEN) == 0 ||
+ strncmp(linuxpps_source[i].info->name, path,
+ LINUXPPS_MAX_NAME_LEN) == 0))
+ break;
+
+ if (i >= LINUXPPS_MAX_SOURCES)
+ return -EINVAL;
+
+ return i;
+}
+
/* --- Input function ------------------------------------------------------ */
static void linuxpps_nl_data_ready(struct sock *sk, int len)
@@ -255,6 +273,25 @@ static void linuxpps_nl_data_ready(struc
break;
}
+ case PPS_FIND_PATH : {
+ source = linuxpps_find_path(nlpps->path);
+ if (source < 0) {
+ dbg("no PPS devices found");
+ nlpps->ret = -ENODEV;
+ break;
+ }
+
+ /* Found! So copy the info */
+ nlpps->source = source;
+ strncpy(nlpps->name, linuxpps_source[source].info->name,
+ LINUXPPS_MAX_NAME_LEN);
+ strncpy(nlpps->path, linuxpps_source[source].info->path,
+ LINUXPPS_MAX_NAME_LEN);
+ nlpps->ret = 0;
+
+ break;
+ }
+
default : {
/* Unknow command */
dbg("unknow command %d", nlpps->cmd);
diff --git a/include/linux/timepps.h b/include/linux/timepps.h
index d623766..499f849 100644
--- a/include/linux/timepps.h
+++ b/include/linux/timepps.h
@@ -153,6 +153,7 @@ struct pps_netlink_msg {
#define PPS_FETCH 6
#define PPS_KC_BIND 7
#define PPS_FIND_SRC 8
+#define PPS_FIND_PATH 9
#ifdef __KERNEL__
@@ -451,5 +452,47 @@ static __inline int time_pps_findsource(
return nlpps.source;
}
+#define PPS_HAVE_FINDPATH 1
+static __inline int time_pps_findpath(char *path, int pathlen, char *idstring, int idlen)
+{
+ int sock;
+ struct sockaddr_nl src_addr, dest_addr;
+ struct pps_netlink_msg nlpps;
+
+ int ret;
+
+ /* Create the netlink socket */
+ ret = socket(PF_NETLINK, SOCK_RAW, NETLINK_PPSAPI);
+ if (ret < 0)
+ return ret;
+ sock = ret;
+
+ /* Bind the socket with the source address */
+ memset(&src_addr, 0, sizeof(src_addr));
+ src_addr.nl_family = AF_NETLINK;
+ src_addr.nl_pid = getpid(); /* self PID as unique ID */
+ src_addr.nl_groups = 0; /* not in mcast groups */
+ ret = bind(sock, (struct sockaddr *) &src_addr, sizeof(src_addr));
+ if (ret < 0) {
+ close(sock);
+ return ret;
+ }
+
+ /* Ask the kernel to destroy the PPS source */
+ nlpps.cmd = PPS_FIND_PATH;
+ strncpy(nlpps.path, path, pathlen);
+ ret = netlink_msg(sock, &nlpps);
+ if (ret < 0) {
+ close(sock);
+ return ret;
+ }
+
+ strncpy(path, nlpps.path, pathlen);
+ strncpy(idstring, nlpps.name, idlen);
+
+ close(sock);
+ return nlpps.source;
+}
+
#endif /* !__KERNEL__ */
#endif /* _SYS_TIMEPPS_H_ */
More information about the LinuxPPS
mailing list