GTA01 shared UART vs. flow control (bug #788)

Werner Almesberger werner at
Tue Jan 22 10:50:12 CET 2008

This is a discussion we're taking from bugzilla to the list, for
greater convenience. The whole background can be found here:

Here's a quick summary. I just stumbled into this one yesterday,
so please excuse (and correct) any misunderstandings.

The problem:

  GTA01 shares its 1st UART between the serial kernel console (i.e.,
  the debug board) and the GSM modem. The UART signals are switched
  between console and GSM with the GSM_EN line. GSM_EN (and another
  signal, simulating the modem's "on" button), is controlled by
  writing to /sys/bus/platform/devices/.../power_on

  The GSM modem has hardware flow control but the console doesn't.

  So what happens is that, if flow control is enabled and the UART
  is switched to the serial console, the next printk will hang the
  kernel, waiting for flow control to signal that data can be sent.

  This state can be reached in various ways:
  - if gsmd terminates without restoring the UART settings, and
    then the UART is switched back to the console
  - if flow control is turned on by accident, while the console is
    active, e.g., if gsmd is started without switching first

Possible solutions:

  There are generally two approaches: 1) symptom treatment, i.e.,
  not making the kernel hang if the console is stuck, and 2) making
  sure we don't enter the problematic configuration.

  In the bugzilla thread, two patches have been submitted that try
  to solve 2). One is fairly straightforward but misses the case
  where flow control is enabled with GSM_EN set to the console. The
  other one handles this case, but is complex and intrusive.

  I've proposed a "just kill flow control" change that also misses
  the scenario where flow control is turned on while GSM_EN selects
  the serial console.

My opinion:

  I think it's generally a sound principle that the kernel should
  try to stay afloat if the serial console gets stuck for some
  reason. So I'd like to see a solution for 1). I've outlined an
  algorithm in bugzilla that would disable serial console output if
  it is stuck for a prolonged time, and automatically re-enable it
  if it becomes unstuck.

  Solving 1) would ensure that the user can recover from the system
  ending up in such an invalid state. (Provided the user is even
  aware of the condition.)

  I'm not sure if we even need to solve 2) if we have a decent
  solution for 1). The main difficulty in solving 2) is that the
  console switching code has to tweak the serial driver settings
  and that the serial driver has to know the state of the console
  switch, so that it can handle requests to enable or disable flow
  control appropriately.

  Naturally, the generic S3C24xx serial driver has no provisions
  for doing such things, which makes any patch trying to address
  this fairly intrusive.

  To me, this looks a bit similar to the dial-in/call-out serial
  devices Unix used to feature in the past. There, you had two
  logical serial devices that really shared the same physical port.

  I'm not sure how hard it would be to put a GSM_EN-aware
  "ttyGTA01gsm/ttyGTA01con" on top of ttySAC0, but if layering
  serial drivers is a feasible approach, this may be quite clean.

  Failing that, a way would have to be found to abstract
  platform-specific handling of flow control out of the general

Related issues:

  In the discussion, also the wish for more advanced features
  appeared. They are a) preserving UART configuration state across
  switches, and b) allowing printks through even if the UART is
  switched to the GSM modem.

  a) would basically correspond to the layered tty case above.
  It gives nice semantics, but from a practical point of view, we
  probably don't care that much - gsmd will take care of getting
  its settings done anyway, and all the console wants is no flow

  b) would be messy since switching to the serial console when a
  random printk comes along would interrupt communication with the
  GSM modem. Now, gsmd seems to have enough issues already if we
  don't make things more interesting by adding sporadic data loss :)

  Besides, there is always dmesg. Now, there's one case where I
  can see a valid exception, and that would be fatal or near-fatal
  errors. In that case, it would be reasonable to just flip the
  UART over to the serial console and let the kernel utter its
  final words. Of course, this should only happen if we actually
  have the serial console enabled.

So, I seems to me we can solve all the practical issues by just
keeping the serial console from getting permanently stuck
irrespective of the cause, as outlined above. That should also be
a nice contribution to the platform-independent S3C4xx driver code.

As far as having a nice and clean way of switching between sets of
parameters is concerned, I'm not sure it's actually worth the
trouble. Getting this right promises to be hard work, and most of
the cases a proper solution would have to handle (bit rate ?)
aren't relevant in our scenario anyway.

Finally, I think a switch-on-panic feature would be useful.

If we agree on this course of action, I'd appreciate tested
patches :) I'm not doing much with GTA01 or GSM at the moment, so
I might very well miss some significant scenarios that should be
verified, so I'd rather leave this to someone who has a greater
itch to scratch ;-)

- Werner

More information about the openmoko-kernel mailing list