2005年10月1日 (土曜日)

12:14:20 # Life 新しい月がはじまりましたね. 気が付いたらLinuxカーネルのLinusのツリーにFUSEがとりこまれていたので, そろそろFUSEでもいじるかな.

update-clusterの問題の修正と, pbuilderの処理. pbuilderを今後共同メンテナンス制に移行します. ずっと同じことをやっているとあきてくるので,新しい人をいれて,いれかえてやるきを生み出すというのは重要ですよね. pbuilderも気づいたら4年以上やっているので,そろそろ新しい風をいれていかないとね.

14:35:34 # Life EUC-JPと,eucJPのどれをつかったらよいのだ,という話題がどこそやらででてきていたので, 調べてみる. ja_JP.eucJPと,ja_JP.EUC-JPの両方が現在利用されている. nl_langinfo(CODESET)でかえってくる値は,eucJPであっても,EUC-JPであっても, 'EUC-JP'になる. シェルから確認するのは,localeコマンドでlocale LC_CTYPE -k コマンドとかで確認できる.他の方法もあったような記憶があるのだが,思い出せない... 結論としては,LC_CTYPEを各アプリケーションから直接解析するのではなく, glibcに処理をまかせてしまえばよいよね,ということでした.

$ LC_ALL=ja_JP.EUC-JP locale  LC_CTYPE -k |grep charmap
charmap="EUC-JP"
$ LC_ALL=ja_JP.eucJP locale  LC_CTYPE -k |grep charmap
charmap="EUC-JP"
$ LC_ALL=ja_JP.utf-8 locale  LC_CTYPE -k |grep charmap
charmap="UTF-8"
	

nl_langinfoを利用する例:

/*BINFMTC:
 */
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <langinfo.h>

main()
{
	setlocale(LC_ALL, "");
	printf("%s\n", nl_langinfo(CODESET));
}

	

16:05:48 # Life bt878ドライバを使ってみるために試行錯誤. alsaでbt87xというオーディオのドライバがある. 以前は,btaudioというOSSのドライバを試したことがあったのだが, なんだか挙動がおかしくてうまく扱えないしろものだった. そこで,alsa版をつかってみようとおもいたったのだが,うまく動かない. modprobe snd-bt87x load_all では何もメッセージが出て来ないし,認識してくれている様子もない.printkデバッグのお時間でしょうか... Documentation/sound/alsa/Bt87x.txtにドキュメントがある. うーん...なんで何もでてこないのだろう.snd_printkは何も出力しないことになっているのか? CONFIG_SND_VERBOSE_PRINTKというのを設定するとどうのこうのというのがあるが, それはちょっと違う.

ちょっとしらべてみると, ALSAのソースとはこの部分が違う. [PATCH] PCI: clean up dynamic pci id logicという,おそらくGregKHのコードで この変更は加えられているようだ. これを使うと,せっかく設定した snd_bt87x_ids という変数がまったく使われずに 初期化されていない driver という変数だけが使われている.これは正しい変更なのか? ソースをよむかぎりでは,pci_match_deviceはpci_match_idを呼んでいる. pci_match_device(drv,dev)はpci_match_id(drv->id_table, dev)と変換される. どうも,ここは pci_match_id(snd_bt87x_ids,pci)と書き直すべき所だったような気がする. pci_match_deviceはdynamic idというのに対応するために拡張されたらしい. ここを若干いじればよさそうだ.とりあえずまずここがNULLを返しているということをprintkデバッグで確認してみるのが第一歩.

--- bt87x.c     2005-04-12 00:58:25.000000000 +0900
+++ /home/dancer/shared/2.6.13/linux-2.6.13/sound/pci/bt87x.c   2005-10-01 15:50:28.000000000 +0900
@@ -798,13 +799,15 @@
        {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */
 };

+static struct pci_driver driver;
+
 /* return the rate of the card, or a negative value if it's blacklisted */
 static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
 {
        int i;
        const struct pci_device_id *supported;

-       supported = pci_match_device(snd_bt87x_ids, pci);
+       supported = pci_match_device(&driver, pci);
        if (supported)
                return supported->driver_data;

	

疑問なのが,上記のようなパッチだけを適用した後で,下記のようなコードがうごくはずないような... 最初にここが呼ばれるうえに,driverが初期化されていないのであれば, 問題がでてきそうな... とおもったら,二度static struct pci_driverというのが宣言されていた.

static int __init alsa_card_bt87x_init(void)
{
        if (load_all)
                driver.id_table = snd_bt87x_default_ids;
        return pci_register_driver(&driver);
}
	
    802 static struct pci_driver driver;
	
    916 static struct pci_driver driver = {
    917         .name = "Bt87x",
    918         .id_table = snd_bt87x_ids,
    919         .probe = snd_bt87x_probe,
    920         .remove = __devexit_p(snd_bt87x_remove),
    921 };
	

試行錯誤. pci_match_device(driver [id_tableを見るため], )ということなので, driver.id_tableは,宣言文でデフォルトの値は snd_bt87x_ids になっているはずだ. snd_bt87x_ids は正しい値になっているはずなので,問題ない気がする. pci_match_deviceで,PCI_ANY_IDになっているばあいの扱いがどうなっているか. subsystem_vendor, subsystem_deviceの値はどうやって確認しているのだろう.

static struct pci_device_id snd_bt87x_default_ids[] = {
	BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 0),
	BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 0),
	{ }
};
	

メモ: デバイスはここにある/sys/bus/pci/devices/0000:03:0b.1, そしてドライバは/sys/bus/pci/drivers/Bt87x

一応念のため,テストコードを書く. static で二度グローバル変数を宣言しても大丈夫か. 期待したように,3,1と出力されるので, 宣言が二度行われても,処理としては,一個が宣言で, 一個が値の定義となってくれて,複数の同じ名前の 変数が定義されてしまったりはしないようだ.

/*BINFMTC:
 */
#include <stdio.h>

struct hoge {
  int value;
};

static struct hoge a;

int edit(struct hoge *a)
{
  a->value=3;
  return 0;
}

int func()
{
  a.value=2;
  edit(&a);
  return 0;
}

static struct hoge a = 
  { .value=1 };

int main()
{
  printf("%i\n", a.value);
  func();
  printf("%i\n", a.value);
  return 0;
}
	

なんか再起動したら動くようになった. しかし,ecasound -i alsahw,1,1,0 -o alsahw,0,0,0としてみるとなにか問題があるようだ. ecasound -f 16,1,32000 -i alsahw,1,1,0 -o alsahw,0,0,0 -b:128などをためしてみるが,あまり改善しない. 最初の一瞬だけ音がでて, その後雑音になる.そして,連続的にXrunが出る.また,一旦 internal RISC errorが出ると音が二度とキャプチャーできなくなる. これはどっかのバッファリングとかタイミングがずれているような雰囲気がするので ちょっと続きがありそうだなぁ...

ecasound[4707] general protection rip:4a4add rsp:7fffffc19000 error:0
ALSA sound/pci/bt87x.c:298: internal RISC error, status 0x20044008
	

今日の作業の結論としては,load_allオプションは動かないが,PCI IDというかsubsystem IDを追加してあげれば認識はする. ただ,ecasoundでの動作試験をしても安定動作もしないし,まともな音も出せなかった.

--- bt87x.c-	2005-10-01 15:48:01.000000000 +0900
+++ bt87x.c	2005-10-02 00:42:26.000000000 +0900
@@ -780,6 +780,7 @@
 	BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
 	BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
 	BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */
+	BT_DEVICE(878, 0x10FC, 0xD018, 32000), /* I-O Data Co. GV-BCTV5/PCI */
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
	
Junichi Uekawa

$Id: dancer-diary.el,v 1.89 2005/05/12 11:19:14 dancer Exp $