ZBOX nano VD01のHDDが遅い (2)
2012/03/03(土) 26:27 NetBSD はてブ情報 はてブに登録 はてブ数

tsutsuiさんから「UDMA が使われているかどうかが気になる」とのコメントとパッチいただきました。

たしかに前回の
viaide0 at pci0 dev 15 function 0: VIA Technologies VX900 SATA Controller (rev. 0x00)
viaide0: VIA Technologies unknown VIA ATA controller
viaide0: bus-master DMA support present
viaide0: primary channel configured to native-PCI mode
viaide0: using ioapic0 pin 21 for native-PCI interrupt
というメッセージをよく見てみるとunknown VIA ATA controllerという表示になっています。

unknownというメッセージを表示しているのはsys/dev/pci/viaide.c#via_chip_map
    540 			default:
    541 		unknown:
    542 				aprint_normal("unknown VIA ATA controller\n");
    543 				sc->sc_wdcdev.sc_atac.atac_udma_cap = 0;
    544 			}
    545 			break;
    546 
という部分です。なるほど、自分でVX900とわかっているわりにはunknownというのはおかしな話です。それもそのはず、tsutsuiさんのパッチではそれをフォローすべく、
@@ -533,6 +538,10 @@ via_chip_map(struct pciide_softc *sc, co
 				aprint_normal("CX700 ATA133 controller\n");
 				sc->sc_wdcdev.sc_atac.atac_udma_cap = 6;
 				break;
+			case PCI_PRODUCT_VIATECH_VX900_IDE:
+				aprint_normal("VX900 ATA133 controller\n");
+				sc->sc_wdcdev.sc_atac.atac_udma_cap = 6;
+				break;
 			case PCI_PRODUCT_VIATECH_VT8251:
 				aprint_normal("VT8251 ATA133 controller\n");
 				sc->sc_wdcdev.sc_atac.atac_udma_cap = 6;
といった具合にVX900であればUDMAを使う、つまりsc->sc_wdcdev.sc_atac.atac_udma_cap = 0ではなくsc->sc_wdcdev.sc_atac.atac_udma_cap = 6という処理をしています。
なるほど。VX900のエントリを追加して動いたと思い込んでいた、ということで、さっそくパッチをあてて動かしてみることにしました。

ところが、認識時のメッセージではあいかわらずunknown VIA ATAといわれてしまいます。

あれれ? と思ってソースを見たところ、unknownが表示されるケースは、
    540 			default:
    541 		unknown:
    542 				aprint_normal("unknown VIA ATA controller\n");
    543 				sc->sc_wdcdev.sc_atac.atac_udma_cap = 0;
    544 			}
    545 			break;
ですから、ラベルがdefaultもしくはunknownということになります。

もし、ラベルがunknownだった場合には、
    471 			if (pci_find_device(&pcib_pa, via_pcib_match) == 0)
    472 				goto unknown;
    473 			pcib_id = pcib_pa.pa_id;
    474 			pcib_class = pcib_pa.pa_class;
    475 			aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
    476 			    "VIA Technologies ");
から飛んでくるので、475行目のVIA Technologiesという文字列は表示されないことになります。ところが、起動時にはVIA Technologiesという表示がされていることから、unknownのラベルからgotoで飛んできているわけではなく、475行目を経由したdefaultの処理としてunknownが表示されていると推測されます。

であれば、switch文の評価でdefaultになっていると判断できるので (caseほげで必ずbreakしているので)、switchの
    477 			switch (PCI_PRODUCT(pcib_id)) {
でVX900にマッチしていないということになります。

意味がどうこう考える前に、PCI_PRODUCT(pcib_id)がどういう値なのか、それを表示させるべく、
    aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
        "VIA Technologies %d, %d", PCI_PRODUCT(pa->pa_id), PCI_PRODUCT(pcib_id));
というデバッグ表示をさせることにしました。今思うと、なんで%dなんかにしたのかと思いますが、
viaide0: VIA Technologies 36865, 33808VX900 ATA133 controller
という表示になりました。

36865は0x9001でVX900のSATAコントローラのIDで、想定どおりです。一方33808は0x8410でPCI_PRODUCT(pcib_id)の値がそれであることがわかりました。

ということでPCI_PRODUCT(pcib_id)が0x8410だからVX900として定義していた0x9001と違うことから結果としてdefaultの処理に飛んでいることがわかり、想定どおり動いていないという理由のつじつまがあいました。

動かない理由を探るべく0x8410という数字が何を意味しているのかを調べるためにVX900のSystem Programming Manualを確認してみたところ、Bus Control And Power ManagementのデバイスIDのようだということがわかりました。

うーん、なんだか変ですねぇ。

ちょっと長くなってきたので、まずはここまで。

1: tsutusi 2012年03月07日(水) 午後7時24分

PCI-ISA bridgeのIDを見なければいけない理由がなんかあったような気がする、
と遠い昔の記憶を掘り起こすためにcvswebでannotateしたところ、
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/pci/pciide.c#rev1.113
この pciide.c rev 1.113 が最初にpcib参照が入ったコードで、それを見るに
当時PCI-IDE DMAが出始めた頃のVIAのチップセットは設計がいまいちで
IDE部分が同じPCI DEVICE IDなのにサポートするUDMA capabilityが違うものが
存在したので、仕方なくチップセットの種類を見るためにPCIBを見るコードにした、
ということだったようです。
それが、いつの間にかIDE自体のPCI DEVICE IDで区別できるデバイスであっても
何も考えずにPCIBを見るように足して行ってしまった、というのが真相ですね。

VX900はどうするべきか、というと、別にPCIBを見なくても判別できるので、
パッチの case PCI_PRODUCT_VIATECH_VX900_IDE: のブロックを一つ上の
switch (PCI_PRODUCT(pa->pa_id)) {
のレベルに持っていけば解決という気がします。
それ以外のものもついでに直すかどうかは偉い人に任せましょう……


名前:  非公開コメント   

  • TB-URL  http://www.tokuda.net/diary/0778/tb/