Search code examples
clinuxserial-porttermios

Input/Output error when getting termios attributes on ttyS0 serial port


I am writing a simple program to open the serial port /dev/ttyS0 which is visible in /dev.

The code opens the serial port no problems on my PC at home but on my work machine I run into an error that returns "Input/Output Error". The error appears as a result of tcgetattr failing but I am unsure why as the serial port is visible. I added a verbose error printout via libexplain and it reported to me.

tcgetattr(fildes = 3 "/dev/ttyS0", data = 0x7FFEEA8CEEB0) failed, Input/output error (5, EIO)

I am not sure what other information is relevant that I can provide. It is an Arch Linux system with a 5.3.8 kernel.

const char *port_name = "/dev/ttyS0";

int main(int argc, char *argv[])
{
   int serial_fd, file_status;
    struct termios termSettings;
    struct sigaction act = { 0 };

    serial_fd = open(port_name, O_RDWR | O_NOCTTY | O_NONBLOCK);

    if (serial_fd < 0) {
        perror("Opening serial port failed");
        return -1;
    }

    if (tcgetattr(serial_fd, &termSettings) < 0) {
        perror("Getting terminal attributes failed");
        printf("Error reason: %s\n",  explain_tcgetattr(serial_fd, &termSettings));
        goto error;
    }
   ...
}

The complete source is here


Solution

  • The dmesg(1) output you show in the comments to your question shows UART: unknown. It seems this can be the problem. It is not recognizing any uart in port 0x3f8, so you seem not to have an uart there (at least, not a standard or compatible one)

    The message normally shows UART: ns16550a or similar, giving you info about the chipset installed there. In your case, the other parameters, show as reserved by the kernel so no other device can use those. I don't know the exact reason why the serial driver does not deallocate the resources and continues, but that's probably some legacy issue also.

    PC based uarts are normally recognized by hardwired configuration only at fixed locations in the system, and are exercised (some inocuous command is sent to see if it responds to it) to be recognized, as they are legacy devices, predating from PnP or PCI devices, so they must be probed by software at well known places. This is what the software is doing.

    If you know there's a physical port device installed, try to use BIOS SETUP to check if the serial port has been enabled in BIOS (if it hasn't you'll not see it at all). Enable it if it hasn't been, and try again.