From 9356b0cb1ef896c485e0855cddb22bb66d83c567 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 2 Jan 2013 15:15:01 -0800 Subject: [PATCH] Changed Linux serial port enumeration to leverage kernel provided device information in /sys/class/tty --- sim_serial.c | 57 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/sim_serial.c b/sim_serial.c index ff9ba2b9..b8df7ab0 100644 --- a/sim_serial.c +++ b/sim_serial.c @@ -866,9 +866,10 @@ return; /* Enumerate the available serial ports. 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 - are ttys (as determined by isatty()) are added to the list. The list - is sorted alphabetically by device name. + /dev/ttyS63 and /dev/ttyUSB0 thru /dev/ttyUSB63 and /dev/tty.serial0 + thru /dev/tty.serial63. Ones we can open and are ttys (as determined + by isatty()) are added to the list. The list is sorted alphabetically + by device name. */ @@ -879,6 +880,46 @@ int port; int ports = 0; memset(list, 0, max*sizeof(*list)); +#if defined(__linux__) +#include +#include +#include +#include +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) { sprintf (list[ports].name, "/dev/ttyS%d", i); 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); } } -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) { sprintf (list[ports].name, "/dev/tty.serial%d", i); 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); } } +#endif return ports; }