YANO's digital garage

Copyright ©YANO All rights reserved. https://www.bravotouring.com/~yano/

Last-modified: 2024-04-17 (水)


[一語一絵/IT系]

CentOSとVT8251 / 2007-05-03 (木)

こないだ失敗したCentOSのSerial ATA対応。[External]VIA VT8251 southbridgeによると「VT8251はkernel 2.6.20でfully supported」だと言われている。

「じゃ、2.6.20.4でも動くはずやん?」と、もう一度/etc/modeprobe.conf

alias scsi_hostadapter ahci
alias scsi_hostadapter1 sata_via
と書いてみたが、やっぱりロードされども実際動かない。こういう時は何はともあれdmesgを確認するのがはじめの一歩。
libata version 2.00 loaded.
ahci 0000:00:0f.0: version 2.0
ACPI: PCI Interrupt 0000:00:0f.0[B] -> GSI 21 (level, low) -> IRQ 21
input: AT Translated Set 2 keyboard as /class/input/input0
ahci 0000:00:0f.0: AHCI 0001.0000 32 slots 4 ports 3 Gbps 0xf impl IDE mode
ahci 0000:00:0f.0: flags: 64bit ncq pm led clo pmp pio slum part
ata1: SATA max UDMA/133 cmd 0xFFFFC20000004D00 ctl 0x0 bmdma 0x0 irq 511
ata2: SATA max UDMA/133 cmd 0xFFFFC20000004D80 ctl 0x0 bmdma 0x0 irq 511
ata3: SATA max UDMA/133 cmd 0xFFFFC20000004E00 ctl 0x0 bmdma 0x0 irq 511
ata4: SATA max UDMA/133 cmd 0xFFFFC20000004E80 ctl 0x0 bmdma 0x0 irq 511
scsi0 : ahci
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
APIC error on CPU0: 00(08)
APIC error on CPU1: 00(08)
ata1.00: qc timeout (cmd 0xec)
ata1.00: failed to IDENTIFY (I/O error, err_mask=0x104)
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
APIC error on CPU0: 08(08)
APIC error on CPU1: 08(08)
ata1.00: qc timeout (cmd 0xec)
ata1.00: failed to IDENTIFY (I/O error, err_mask=0x104)
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
APIC error on CPU0: 08(08)
APIC error on CPU1: 08(08)
ata1.00: qc timeout (cmd 0xec)
ata1.00: failed to IDENTIFY (I/O error, err_mask=0x104)
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
scsi1 : ahci
ata2: SATA link down (SStatus 0 SControl 300)
scsi2 : ahci
ata3: SATA link down (SStatus 0 SControl 300)
scsi3 : ahci
ata4: SATA link down (SStatus 0 SControl 300)
どうやらシリアルATAコントローラーは認識しているもののHDDとの通信エラーになっているようだ。という事がわかったところでここから先の手の打ちようが無い事には変わりない。

今度は[External]VIA Arena - VT8251 Linux Supportを頼りに再チャレンジ。kernel 2.6.15~17用のpatchがあるというので、ごにょごにょ2.6.17.14に適用してみたところ、うまく動いた

dmesgを確認するとこんな感じ。

libata version 1.20 loaded.
ahci 0000:00:0f.0: version 1.2
GSI 18 sharing vector 0xB9 and IRQ 18
ACPI: PCI Interrupt 0000:00:0f.0[B] -> GSI 21 (level, low) -> IRQ 185
input: AT Translated Set 2 keyboard as /class/input/input0
ahci 0000:00:0f.0: AHCI 0001.0000 32 slots 4 ports 3 Gbps 0xf impl IDE mode
ahci 0000:00:0f.0: flags: 64bit ncq pm led clo pmp pio slum part
ata1: SATA max UDMA/133 cmd 0xFFFFC20000004D00 ctl 0x0 bmdma 0x0 irq 201
ata2: SATA max UDMA/133 cmd 0xFFFFC20000004D80 ctl 0x0 bmdma 0x0 irq 201
ata3: SATA max UDMA/133 cmd 0xFFFFC20000004E00 ctl 0x0 bmdma 0x0 irq 201
ata4: SATA max UDMA/133 cmd 0xFFFFC20000004E80 ctl 0x0 bmdma 0x0 irq 201
ata1: SATA link up 3.0 Gbps (SStatus 123)
ata1: dev 0 cfg 49:2f00 82:746b 83:7f01 84:4023 85:7469 86:3e01 87:4023 88:407f
ata1: dev 0 ATA-7, max UDMA/133, 488397168 sectors: LBA48
ata1: dev 0 configured for UDMA/133
scsi0 : ahci
ata2: SATA link down (SStatus 0)
scsi1 : ahci
ata3: SATA link down (SStatus 0)
scsi2 : ahci
ata4: SATA link down (SStatus 0)
scsi3 : ahci
  Vendor: ATA       Model: WDC WD2500KS-00M  Rev: 02.0
  Type:   Direct-Access                      ANSI SCSI revision: 05
SCSI device sda: 488397168 512-byte hdwr sectors (250059 MB)
sda: Write Protect is off
sda: Mode Sense: 00 3a 00 00
SCSI device sda: drive cache: write back
SCSI device sda: 488397168 512-byte hdwr sectors (250059 MB)
sda: Write Protect is off
sda: Mode Sense: 00 3a 00 00
SCSI device sda: drive cache: write back
sda: sda1
sd 0:0:0:0: Attached scsi disk sda
と言うわけで、2.6.20はどこかでirqを間違ってるクサいなぁ。

hdparm

# /sbin/hdparm /dev/hda

/dev/hda:
 multcount    = 16 (on)
 IO_support   =  1 (32-bit)
 unmaskirq    =  1 (on)
 using_dma    =  1 (on)
 keepsettings =  0 (off)
 readonly     =  0 (off)
 readahead    = 256 (on)
 geometry     = 30401/255/63, sectors = 250059350016, start = 0
となっていて、パラレルATAもDMAモードになっているので問題無し。まぁ2.6.17で不都合があるわけではないので、これで良いかな。

試しに最新の2.6.20.4のソースを確認したのだが、ahci.cには既に同等のロジックが入っていた。どうやら2.6.19からSATAサポートがSCSIセクションからATAセクションに移動したので、そのあたりに問題が潜んでいるのかも知れない。

ちなみにVT8251用のpatchを当てたのはdrivers/scsi/ahci.cだけで、差分は以下の通り。

--- linux-2.6.17.14/drivers/scsi/ahci.c.orig    2006-10-14 03:55:04.000000000 +0900
+++ linux-2.6.17.14/drivers/scsi/ahci.c 2007-05-03 17:36:36.000000000 +0900
@@ -73,6 +73,7 @@
        RX_FIS_D2H_REG          = 0x40, /* offset of D2H Register FIS data */

        board_ahci              = 0,
+       board_ahci_vt8251       = 1,

        /* global controller registers */
        HOST_CAP                = 0x00, /* host capabilities */
@@ -153,6 +154,9 @@

        /* hpriv->flags bits */
        AHCI_FLAG_MSI           = (1 << 0),
+
+       /* ap->flags bits */
+       AHCI_FLAG_RESET_NEEDS_CLO       = (1 << 24),
};

struct ahci_cmd_hdr {
@@ -255,6 +259,16 @@
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &ahci_ops,
        },
+       /* board_ahci_vt8251 */
+       {
+               .sht            = &ahci_sht,
+               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+                                 AHCI_FLAG_RESET_NEEDS_CLO,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .port_ops       = &ahci_ops,
+       },
};

static const struct pci_device_id ahci_pci_tbl[] = {
@@ -296,6 +310,8 @@
          board_ahci }, /* ATI SB600 non-raid */
        { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_ahci }, /* ATI SB600 raid */
+       { PCI_VENDOR_ID_VIA, 0x3349, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+         board_ahci_vt8251 }, /* VT8251 */
        { }     /* terminate list */
};

@@ -534,9 +550,27 @@
        return -1;
}

-static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
+static int ahci_clo(struct ata_port *ap)
{
+       void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
        struct ahci_host_priv *hpriv = ap->host_set->private_data;
+       u32 tmp;
+
+       if (!(hpriv->cap & HOST_CAP_CLO))
+               return -EOPNOTSUPP;
+
+       tmp = readl(port_mmio + PORT_CMD);
+       tmp |= PORT_CMD_CLO;
+       writel(tmp, port_mmio + PORT_CMD);
+
+       if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0, 1, 500))
+               return -EIO;
+
+       return 0;
+}
+
+static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
+{
        struct ahci_port_priv *pp = ap->private_data;
        void __iomem *mmio = ap->host_set->mmio_base;
        void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
@@ -564,23 +598,13 @@
        /* check BUSY/DRQ, perform Command List Override if necessary */
        ahci_tf_read(ap, &tf);
        if (tf.command & (ATA_BUSY | ATA_DRQ)) {
-               u32 tmp;
+               rc = ahci_clo(ap);

-               if (!(hpriv->cap & HOST_CAP_CLO)) {
-                       rc = -EIO;
-                       reason = "port busy but no CLO";
+               if (rc == -EOPNOTSUPP) {
+                       reason = "port busy but CLO unavailable";
                        goto fail_restart;
-               }
-
-               tmp = readl(port_mmio + PORT_CMD);
-               tmp |= PORT_CMD_CLO;
-               writel(tmp, port_mmio + PORT_CMD);
-               readl(port_mmio + PORT_CMD); /* flush */
-
-               if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0,
-                                      1, 500)) {
-                       rc = -EIO;
-                       reason = "CLO failed";
+               } else if (rc == -EIO) {
+                       reason = "port busy but CLO failed";
                        goto fail_restart;
                }
        }
@@ -694,6 +718,12 @@

 static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes)
 {
+       if ((ap->flags & AHCI_FLAG_RESET_NEEDS_CLO) &&
+           (ata_busy_wait(ap, ATA_BUSY, 1000) & ATA_BUSY)) {
+               /* ATA_BUSY hasn't cleared, so send a CLO */
+               ahci_clo(ap);
+       }
+
        return ata_drive_probe_reset(ap, ata_std_probeinit,
                                     ahci_softreset, ahci_hardreset,
                                    ahci_postreset, classes);

【参照】
●VIA Arena Forum http://forums.viaarena.com/
VT8251 Linux Support 2006年4月18日
●VIA VT8251 southbridge http://via8251.la-evento.com/


[一語一絵]

なんとなく福岡 / 2007-05-03 (木)

西国寺参道
4/8 尾道市西国寺にて

今日から始まった[External]博多どんたくが過去最高の110万人を記録。

お約束のGW渋滞も九州道広川インターチェンジを先頭にした60kmが一番長かったそうだし、[External]高校野球特待制度も福岡が26校でこれも全国一。

何はともあれ、一番という響きは悪くないぢゃないか。

昨日はマー君にいいようにやられた[External]ホークスも、今日は借りは返すとばかりに今季最多の17安打で快勝し、20勝一番乗り。首位のライオンズとゲーム差無しの2位なので、こちらも連休明けには首位返り咲きを期待したい。

[External]アビスパ福岡のFWリンコンが2発を決め、J2の首位に。今シーズンから加入の[External]リンコンだが出場8試合で7点を稼ぎ出して目下得点ランキング2位の大活躍。

特に今日の2点目は美しいワンツーから繰り出された実にエクセレントなゴールで、つい油断から出掛けそびれ見逃したのは残念だった。リティの目指す攻撃サッカーが早くも実を結びつつあるようなので、次節13(日)の京都戦にはぜひスタジアムへ足を運んでライブで観ておきたい。

【参照】
●九州 : nikkansports.com http://kyusyu.nikkansports.com/
九州、山口は80校/高校野球特待制度申告 2007年5月2日
博多どんたく、過去最高の110万人 2007年5月3日
福岡がFWリンコン2発で単独首位 2007年5月3日
●福岡ソフトバンクホークス http://www.softbankhawks.co.jp/
●アビスパ福岡 http://www.avispa.co.jp/