web-dev-qa-db-ja.com

マルチポートカードのシリアルポートの再注文

2つのオンボードシリアルポートを備えたRedHat Enterprise 6.2マシンと、8つの追加シリアルポートを備えたPCIeカード(16C950 UART、16C550準拠)があります。カーネルオプション8250.nr_uarts=10を追加して、すべてのデバイスが/devの下に表示されるようにしました。

2つのオンボードデバイスは予想どおりttyS0とttyS1として表示されますが、PCIeカードのシリアルポートは、期待どおりにI/Oポートによって順序付けられていません。それ以外の場合、デバイスは正常に動作します。ttyの順序がボードのブレークアウトケーブルの順序と一致しないのは、あまりエレガントではないということです。順序を変更する方法について何かアイデアはありますか?

出力フォームsetserial

# setserial -g /dev/ttyS*
/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: 16550A, Port: 0x02f8, IRQ: 3
/dev/ttyS2, UART: 16650, Port: 0xdf30, IRQ: 30
/dev/ttyS3, UART: 16650, Port: 0xdf38, IRQ: 30
/dev/ttyS4, UART: 16650, Port: 0xdf00, IRQ: 30      <-- Why is this one not ttyS2?
/dev/ttyS5, UART: 16650, Port: 0xdf08, IRQ: 30
/dev/ttyS6, UART: 16650, Port: 0xdf10, IRQ: 30
/dev/ttyS7, UART: 16650, Port: 0xdf18, IRQ: 30
/dev/ttyS8, UART: 16650, Port: 0xdf20, IRQ: 30
/dev/ttyS9, UART: 16650, Port: 0xdf28, IRQ: 30

dmesgを見ると、正しい順序でそれらが見つかりますが、最も低いI/OポートをttyS4から開始します。

# dmesg | grep ttyS
serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
00:06: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
00:07: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
0000:05:00.0: ttyS4 at I/O 0xdf00 (irq = 30) is a ST16650
0000:05:00.0: ttyS5 at I/O 0xdf08 (irq = 30) is a ST16650
0000:05:00.0: ttyS6 at I/O 0xdf10 (irq = 30) is a ST16650
0000:05:00.0: ttyS7 at I/O 0xdf18 (irq = 30) is a ST16650
0000:05:00.0: ttyS8 at I/O 0xdf20 (irq = 30) is a ST16650
0000:05:00.0: ttyS9 at I/O 0xdf28 (irq = 30) is a ST16650
0000:05:00.0: ttyS2 at I/O 0xdf30 (irq = 30) is a ST16650
0000:05:00.0: ttyS3 at I/O 0xdf38 (irq = 30) is a ST16650

setserialを使用してポートを変更しようとしても機能しないようですが、常にデバイスがビジーであると報告されます(これは再起動によるもので、デバイスに何もアクセスしていません)。

# setserial /dev/ttyS2 port 0xdf00
Cannot set serial info: Device or resource busy

編集:Gillesから提供された情報のおかげで、順序付けられた[〜#〜] name [〜#〜]を書き込むudevを使用して、現在ほとんど機能しています。 [〜#〜] kernel [〜#〜]名前。 udevadm infoからの出力は、個々のデバイスを一意に識別するために使用できる唯一のパラメーターであることを示しています(ttyS [2-9]は、[〜#〜 ] kernel [〜#〜]パラメータ)。

# udevadm info -a -n /dev/ttyS2
  looking at device '/devices/pci0000:00/0000:00:07.0/0000:05:00.0/tty/ttyS2':
    KERNEL=="ttyS2"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:07.0/0000:05:00.0':
    KERNELS=="0000:05:00.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="serial"
    ATTRS{vendor}=="0x494f"
    ATTRS{device}=="0x10a9"
    ATTRS{subsystem_vendor}=="0x0000"
    ATTRS{subsystem_device}=="0x0000"
    ATTRS{class}=="0x070002"
    ATTRS{irq}=="30"
    ATTRS{local_cpus}=="0000ff"
    ATTRS{local_cpulist}=="0-7"

私の新しいudevルール:

SUBSYSTEM=="tty", DRIVERS=="serial", ATTRS{vendor}=="0x494f", KERNEL=="ttyS4", NAME="ttyS2"
# [snipped 7 more rules for each device]
5
Linville

dev ルールを使用してデバイス名を変更できるはずです。実行 udevadm info -a -n /dev/ttyS2 デバイスの特性を取得します。マルチポートカードを一意に識別する属性と、ポートを識別する1つの属性を見つけます。次に、ポートごとにudevルールを記述します。ルールは次のようになります。

SUBSYSTEM=="tty", DRIVERS=="serial", ATTRS{vendor}=="Yoyodyne", ATTRS{port}=="0xdf00", NAME="ttyS2"
SUBSYSTEM=="tty", DRIVERS=="serial", ATTRS{vendor}=="Yoyodyne", ATTRS{port}=="0xdf80", NAME="ttyS3"
…

実行 udevadm trigger (右の--attr-match-…オプション)すでに接続されているデバイスにルールを再適用します。