A.1. Linux カーネルのフロー制御

console= パラメータに r オプションを付けて、 Linux カーネルに CTS/RTS のフロー制御をさせることができます。 例えば、速度が 9600bps、データが 8 ビット、 パリティ無し、CTS/RTS のフロー制御、というシリアルリンクは、 Figure A-1 で示すように設定します。

Figure A-1. CTS/RTS フロー制御を行なう、カーネルの console パラメータ

console=9600n8r

Linux カーネルは常にデータを送出するだけなので、 CTS/RTS フロー制御は、 "Clear to Send" がアサートされていないことを確認する という実装になっています。 この部分のコードは、 /usr/src/linux/drivers/char/serial.c にあります。 関連部分は Figure A-2 にあります。

Figure A-2. コンソールの CTS/RTS フロー制御用カーネルソースコード

static inline void wait_for_xmitr(struct async_struct *info)
{
…
  /* Wait for flow control if necessary */
  if (info->flags & ASYNC_CONS_FLOW) {
    tmout = 1000000;
    while (--tmout &&
           ((serial_in(info, UART_MSR) & UART_MSR_CTS) == 0));
  }       
}

tmout 値を 1000000 にしてループすることで、 CTS ラインがアサート状態になるまで、1 秒ほど待つことになります。

このコードでは、 RS-232 の "Data Set Ready" と "Data Carrier Detect" の両ステータスラインからのステータスを無視しています。 しかし、こうしてしまうと、多くの不都合が出てきます。

こういうバグがあるので、この HOWTO では、 カーネルレベルのフロー制御は、もうお奨めしません。 筆者は、現在報告されているバグすべてを修復するパッチを持っており、 カーネル本体にこのパッチを取り込んでもらおうとしています。 カーネルのこのバグが修正されてしまえば、 この HOWTO では、 再度カーネルレベルのフロー制御をお奨めしたいと思います。