3. kernel-2.0.35(or 36) で ATAPI-PD を使うには

2.0.35(or 36) ではなぜか PD が常に read only で認識されるという問題が あります。これを回避するためには、kernel source の drivers/scsi/ide-scsi.c の 150-200 行目のあたりを 2.0.33 と同じにする ことが必要なようです。この方法ではもしかしたらなにか問題があるの かもしれませんが、少くともうちでは安定動作しています。 以下は、2.0.35 (or 36) で ATAPI-PD を使う patch です。fj.os.linux で高 垣さんというかたが、2.0.34 用の patch を公開されてた [1] のですが、 なぜかうまくあてられなかったので、それを参考にして作りました。

以下を切り取って、ide-scsi.c.diff とでも名付けて保存して、 drivers/scsi/ で、

  $ patch < ide-scsi.c.diff

などとしてあててください。あとは 1 章に従って make するだけです。

--------- ここから -----------
*** linux/drivers/scsi/ide-scsi.c.35.org	Mon Nov 16 21:45:00 1998
--- linux/drivers/scsi/ide-scsi.c	Tue Nov 17 05:07:21 1998
***************
*** 156,162 ****
  static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc)
  {
  	idescsi_scsi_t *scsi = drive->scsi;
! 	u8 *c = pc->c;
  
  	if (scsi->media == TYPE_ROM) {
  		if (c[0] == READ_6 || c[0] == WRITE_6) {
--- 156,163 ----
  static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc)
  {
  	idescsi_scsi_t *scsi = drive->scsi;
! 	u8 *c = pc->c, *buf = pc->buffer, *sc = pc->scsi_cmd->cmnd;
! 	int i;
  
  	if (scsi->media == TYPE_ROM) {
  		if (c[0] == READ_6 || c[0] == WRITE_6) {
***************
*** 164,169 ****
--- 165,178 ----
  			c[3] = c[1] & 0x1f;	c[2] = 0;		c[1] &= 0xe0;
  			c[0] += (READ_10 - READ_6);
  		}
+ 		if (c[0] == MODE_SENSE || (c[0] == MODE_SELECT && buf[3] == 8)) {
+ 		        pc->request_transfer -= 4;
+ 		        memset (c, 0, 12);
+ 		        c[0] = sc[0] | 0x40;c[2] = sc[2];c[8] = sc[4] - 4;
+ 		        if (c[0] == MODE_SENSE_10) return;
+ 		        for (i = 0; i <= 7; i++) buf[i] = 0;
+ 		        for (i = 8; i < pc->buffer_size - 4; i++) buf[i] = buf[i + 4];
+ 		}
  	}
  }
  
***************
*** 171,181 ****
  {
  	idescsi_scsi_t *scsi = drive->scsi;
  	u8 *buf = pc->buffer;
  
  	if (scsi->media == TYPE_ROM) {
! 		if (pc->c[0] == INQUIRY)
! 			buf[2] |= 2;
! 	}
  }
  
  static inline void idescsi_free_bh (struct buffer_head *bh)
--- 180,198 ----
  {
  	idescsi_scsi_t *scsi = drive->scsi;
  	u8 *buf = pc->buffer;
+ 	int i;
  
  	if (scsi->media == TYPE_ROM) {
! 	        if (pc->c[0] == MODE_SENSE_10 && pc->scsi_cmd->cmnd[0] == MODE_SENSE) {
! 	                buf[0] = buf[1];buf[1] = buf[2];
! 			buf[2] = 0;buf[3] = 8;
! 			for (i = pc->buffer_size - 1; i >= 12; i--)
! 			buf[i] = buf[i - 4];
! 			for (i = 11; i >= 4; i--) buf[i] = 0;
! 		}
! 	        if (pc->c[0] == INQUIRY)
! 	                buf[2] |= 2;
!         }
  }
  
  static inline void idescsi_free_bh (struct buffer_head *bh)
--------- ここまで -----------

Notes

[1]

fj.os.linux
Message-ID: <35D6E360.AF9D2BED@st.rim.or.jp>