select not working correctly on usb -> serial device

Hello,
I have a simple piece of software that works correctly on a desktop unit, but does not work correctly on a Lenovo Thinkpad W540. I am trying to understand why.
The code is:


    while(true) {
        FD_ZERO(&rfds);
        FD_ZERO(&wfds);
        FD_ZERO(&efds);

        FD_SET(fd, &wfds);                                    /* set the select check bit */
        FD_SET(fd, &rfds);
        FD_SET(fd, &efds);
        ...

        retval = select(fd + 1, &rfds, &wfds, &efds, &tv);        /* wait for non-blocking i/o availability */

        if (retval <= 0)            /* error or time out */
            return retval;

        if(FD_ISSET(fd, &wfds)){            /* writing to do, and channels unblocked */
            int ret = write(fd, ((char *) wrBuf) + wrBufPt, wrLenBytes);
            if (ret < 0)return ret;            /* error on write */
            ...
            continue;
        }
   ...
   }

The file descriptor (fd) has been opened on a USB port that has a Exar USB-> serial device plugged in to it (/dev/ttyXRUSB0). The write buffer should always be able to accept a non-blocking write, so the select should always return with the wfds set such that the FD_ISSET() should return true. This works correctly on the desktop; but it never returns true on the w540 laptop–the select always times out and returns with a value of 0. When I debug this, I can force a write to the file descriptor, it it works fine–no blocking–and the characters are transmitted to the serial device.

For some reason, on the laptop, the select will not trigger when the fd is available for writing. The select does appear to work and will trigger if there are characters available for reading in the read buffer.

I am running tumbleweed “Linux 5.0.6-1-default #1 SMP Thu Apr 4 04:40:16 UTC 2019 (dff56e4) x86_64 x86_64 x86_64 GNU/Linux” on both devices. I have tried both the usb 2.0 and usb 3.0 ports on the laptop. I am using exar’s linux device handler (xr21b1411) and I have installed this handler in both destop and laptop.

I probably can work around this by not using the select for writes; but I would like to understand what is going on.

Thanks for your help.

Corrected:
I just tested the select function again on the laptop, and it looks like rfds is NOT set even when there are characters available for reading. So, on the laptop, the select function does not appear to be able to detect that availability of non-blocking i/o options.

You might consider to explain at least what computer language a piece of code is supposed to be in, when you want people to help you with it.

Als remind that there is a sub-forum for Development > Programming/Scripting. Many people will only look to certain sub-forums and then just browse the titles. Thus choosing the most fitting sub-forums and having keywords in your title is important to draw the attention of the people you need.

Thanks for your suggestions.

The language that I am using is C/C++. I have just included a small segment of the code that will demonstrate my problem.

I am not so much interested in someone helping me with the code–instead I am sort of looking for some insight as to why a laptop USB port would behave differently than a desktop.

I am familiar with writing device drivers for operating systems but I have never written one for Linux. I did buy some books (Linux Device Drivers, and How to write Linux device drivers) in the hope that I can dig through Exar’s device handler and find the problem.

It does look like the problem is somewhat above the Exar device handler, as I am using the same handler on both the desktop and the laptop. I am guessing that when I installed tumbleweed, it loaded one USB handler for the desktop, and a different handler for the laptop–though I really don’t know how this works. I am wondering if somehow, the laptop USB system is generating interrupts differently, or something.

I am really at a loss–I sort of assumed that USB systems had been standardized to the point that the same software would work the same on any USB port.

I think that I just need to dig through the handler code to figure out how USBs work on Linux, and maybe I will get some insight from this.

Maybe someone has had some experience writing USB drivers and they can point me in some direction.

Thanks,
Greg Laird

Hi
Looking at the driver it’s for USB 2.0 only, can you confirm via the commands usb-devices and lsusb -t it’s connecting up the same and using the driver you expected.

Could it be a permissions, if your running as your user, add the user to the dialout group.