title: Why is tcsendbreak() necessary for serial communication to start working?
body: <p>We are migrating from an older OS <code>(OpenSuse 10.2)</code> to <code>Ubuntu 16.04</code>, and one of our applications communicates via a serial port. Communication stopped working on Ubunutu, but with a small hack(?) it does start working. That hack is to send a <code>tcsendbreak(</code>) right after the call to open, like so:</p>
  
  <pre><code>fd = open(pname, O_RDWR | O_NOCTTY); //pname becomes /dev/ttyS6
  if (fd &lt; 0)
  {
      printf("Couldnt open comms port \"%s\".\n", pname);
      return SYSERR;
  }
  if (tcsendbreak(fd, 0) &lt; 0)
  {
      printf("tcsendbreak error\n");
  }
  </code></pre>
  
  <p>After doing this everything runs normally. I've tried doing a tcflush at various points (without the tcsendbreak), that didn't make a difference. </p>
  
  <p>What are some reasons why the tcsendbreak would allow communication to be established? Any ideas of what to try without using the tcsendbreak? Trying to understand why its needed, and if there is an underlying issue that this break skips past.</p>
  
  <p>We set the modes the following way:</p>
  
  <pre><code>int r = 0;
  struct termios port_opt, *popt;
  
  r |= tcgetattr(fd, &amp;original_port_options);
  port_opt = original_port_options;
  popt = &amp;port_opt;
  cfmakeraw(&amp;port_opt);
  /* parity/framing errors come in as nulls. */
  popt-&gt;c_iflag |= (IGNBRK);
  popt-&gt;c_cflag |= (CLOCAL);
  popt-&gt;c_cc[VMIN] = 0;   /* ignored by line discipline. */
  popt-&gt;c_cc[VTIME] = 1;  /* ignored by line discipline. */
  popt-&gt;c_cflag |= CREAD; //enable receiver
  r |= cfsetispeed(popt, B19200); 
  popt-&gt;c_cflag &amp;= ~(PARENB);/* turn off parity. */
  popt-&gt;c_cflag = (popt-&gt;c_cflag &amp; ~CSIZE) | CS8; /* 8 bits. */
  popt-&gt;c_cflag &amp;= ~CSTOPB; /* only 1 stop bit. */
  r |= cfsetospeed(popt, B19200);
  r |= tcsetattr(fd, TCSANOW, popt);
  if (r != 0)
      gos_panic("Cant set comms driver parameters");
  </code></pre>
  
  <p>Additionally, we also set a line discipline:</p>
  
  <pre><code>r = ioctl(fd, TIOCGETD, &amp;old_line_discipline);
  if (r != 0)
      old_line_discipline = -1;
  r = map_line_discipline("LINE_DISC", 27);
  r = ioctl(fd, TIOCSETD, &amp;r);
  </code></pre>
  
  <p>Note that communication works when sending the tcsendbreak before setting all these modes.</p>