Changed Linux serial port enumeration to leverage kernel provided device information in /sys/class/tty

This commit is contained in:
Mark Pizzolato 2013-01-02 15:15:01 -08:00
parent 2af67a75b0
commit 9356b0cb1e

View file

@ -866,9 +866,10 @@ return;
/* Enumerate the available serial ports. /* Enumerate the available serial ports.
The serial port names generated by attempting to open /dev/ttyS0 thru The serial port names generated by attempting to open /dev/ttyS0 thru
/dev/ttyS53 and /dev/ttyUSB0 thru /dev/ttyUSB0. Ones we can open and /dev/ttyS63 and /dev/ttyUSB0 thru /dev/ttyUSB63 and /dev/tty.serial0
are ttys (as determined by isatty()) are added to the list. The list thru /dev/tty.serial63. Ones we can open and are ttys (as determined
is sorted alphabetically by device name. by isatty()) are added to the list. The list is sorted alphabetically
by device name.
*/ */
@ -879,6 +880,46 @@ int port;
int ports = 0; int ports = 0;
memset(list, 0, max*sizeof(*list)); memset(list, 0, max*sizeof(*list));
#if defined(__linux__)
#include <dirent.h>
#include <libgen.h>
#include <unistd.h>
#include <sys/stat.h>
if (1) {
struct dirent **namelist;
int n;
struct stat st;
n = scandir("/sys/class/tty/", &namelist, NULL, NULL);
while (n--) {
if (strcmp(namelist[n]->d_name, ".") &&
strcmp(namelist[n]->d_name, "..")) {
char path[1024], devicepath[1024], driverpath[1024];
sprintf (path, "/sys/class/tty/%s", namelist[n]->d_name);
sprintf (devicepath, "/sys/class/tty/%s/device", namelist[n]->d_name);
sprintf (driverpath, "/sys/class/tty/%s/device/driver", namelist[n]->d_name);
if ((lstat(devicepath, &st) == 0) && S_ISLNK(st.st_mode)) {
char buffer[1024];
memset (buffer, 0, sizeof(buffer));
if (readlink(driverpath, buffer, sizeof(buffer)) > 0) {
sprintf (list[ports].name, "/dev/%s", basename (path));
port = open (list[ports].name, O_RDWR | O_NOCTTY | O_NONBLOCK); /* open the port */
if (port != -1) { /* open OK? */
if (isatty (port)) /* is device a TTY? */
++ports;
close (port);
}
}
}
}
free (namelist[n]);
}
free (namelist);
}
#else /* Non Linux, just try some well known device names */
for (i=0; (ports < max) && (i < 64); ++i) { for (i=0; (ports < max) && (i < 64); ++i) {
sprintf (list[ports].name, "/dev/ttyS%d", i); sprintf (list[ports].name, "/dev/ttyS%d", i);
port = open (list[ports].name, O_RDWR | O_NOCTTY | O_NONBLOCK); /* open the port */ port = open (list[ports].name, O_RDWR | O_NOCTTY | O_NONBLOCK); /* open the port */
@ -897,15 +938,6 @@ for (i=0; (ports < max) && (i < 64); ++i) {
close (port); close (port);
} }
} }
for (i=0; (ports < max) && (i < 64); ++i) {
sprintf (list[ports].name, "/dev/ttyAMA%d", i);
port = open (list[ports].name, O_RDWR | O_NOCTTY | O_NONBLOCK); /* open the port */
if (port != -1) { /* open OK? */
if (isatty (port)) /* is device a TTY? */
++ports;
close (port);
}
}
for (i=1; (ports < max) && (i < 64); ++i) { for (i=1; (ports < max) && (i < 64); ++i) {
sprintf (list[ports].name, "/dev/tty.serial%d", i); sprintf (list[ports].name, "/dev/tty.serial%d", i);
port = open (list[ports].name, O_RDWR | O_NOCTTY | O_NONBLOCK); /* open the port */ port = open (list[ports].name, O_RDWR | O_NOCTTY | O_NONBLOCK); /* open the port */
@ -915,6 +947,7 @@ for (i=1; (ports < max) && (i < 64); ++i) {
close (port); close (port);
} }
} }
#endif
return ports; return ports;
} }