Buffalo: DIU-B80G (0411:001d)

この馬齢10年を越える USB1.1/IEEE1394/IDE ブリッジも、 USB で接続して、 カーネル 3.14.16 以降を用いて Ext3 ファイルシルテムをマウントしようとすると、 Myson Century USB2.0/ATAPI Bridge (04cf:8818) と同様の問題が発生して、

end_request: critical target error, dev sdb, sector 12293933
Buffer I/O error on device sdb2, logical block 526
lost page write due to I/O error on sdb2
Aborting journal on device sdb2.
end_request: critical target error, dev sdb, sector 0

などとエラーが出る。 解決策は 04cf:8818 の場合と同じで、

modprobe usb-storage quirks=0x0411:0x001d:w

とやってモジュールをロードすればよい。 Myson のケースの設定とあわせて modprobe.conf などに記述するには

options usb-storage quirks=0x04cf:0x8818:w,0x0411:0x001d:w

のようにコンマで区切って書く。

ただしこのブリッジを USB1.1 接続で使用するのは堪えられぬほど低速なので、 IEEE1394 で接続したい。 しかるにこれを Linux カーネルの firewire-sbp2 ドライバをつかって接続してマウントしようとすると、 やはり上記のようなエラーが出る。 firewire-sbp2 ドライバには usb-storage ドライバのような quirks パラメータの設定が無いので、ここはひとつカーネルのソースコードをいじくって、必要な設定を加えねばならない。

usb-storage ドライバの scsiglue.c というファイルを見ればわかるが、この write-protect チェックの省略は、 sdev->skip_ms_page_3f = 1; という SCSI 機器用のコードで指定されている。 これを DIU-B80G の IEEE1394 でも指定できればよい。 それには sbp2.c を次のように修正する:

--- linux-3.17.4/drivers/firewire/sbp2.c.orig
+++ linux-3.17.4/drivers/firewire/sbp2.c
@@ -109,6 +109,7 @@
 #define SBP2_WORKAROUND_DELAY_INQUIRY	0x10
 #define SBP2_INQUIRY_DELAY		12
 #define SBP2_WORKAROUND_POWER_CONDITION	0x20
+#define SBP2_WORKAROUND_MODE_SENSE_3F	0x40
 #define SBP2_WORKAROUND_OVERRIDE	0x100
 
 static int sbp2_param_workarounds;
@@ -121,6 +122,7 @@
 	", delay inquiry = "      __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
 	", set power condition in start stop unit = "
 				  __stringify(SBP2_WORKAROUND_POWER_CONDITION)
+	", skip mode page 3f = "   __stringify(SBP2_WORKAROUND_MODE_SENSE_3F)
 	", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
 	", or a combination)");
 
@@ -1570,6 +1572,9 @@
 	if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
 		blk_queue_max_hw_sectors(sdev->request_queue, 128 * 1024 / 512);
 
+	if (lu->tgt->workarounds & SBP2_WORKAROUND_MODE_SENSE_3F)
+		sdev->skip_ms_page_3f = 1;
+
 	return 0;
 }
 

そうやってビルドしたモジュールをば

modprobe firewire-sbp2 workarounds=0x44

とやって読み込むか、 あるいは modprobe.conf などに

options firewire-sbp2 workarounds=0x44

と書いて depmod -a とやっておけばよい。

上記のコードは 3.17.4 を修正したときのものだが、 同じ修正で 3.14 でも使えるし、おそらく 3.18 にも適用できると思われる。 sbp2-3.14.patch.gz をカーネルソースツリーにコピーして

zcat sbp2-3.14.patch.gz | patch -b -p1

とやってビルドすればよい。

2014年8月の SCSI lib の変更