差分表示
- 最後の更新で追加された行はこのように表示します。
- 最後の更新で削除された行は
このように表示します。
*SCSIコマンドに関して
*実装
SCSIコマンドには沢山あるが、大雑把に大別するとデバイスに記録されているデータをrwするコマンド(READ/WRITE)とデバイスを制御/診断するもの(INQUIRY/FORMAT/READ ATTRIBUTE)とかがあるっぽい。どんなのあるかの詳しくはwikiとか仕様書とかを参照ってことでw
コード例がLinuxのHowToにあるが、あれはSGドライバのVersion 3.0以前のdriverを
直接 read/writeしてデータブロックをやり取りするのものだが、3.0以降は
SGドライバに SG_IOと言うioctl()が新設されており、こちらを利用して
SCSIのデータブロックをrwするのが、現在のトレンドだとおもう、多分w
*コード例
ってことで、例によって後は実装で
HowToで提供されている handle_scsi_cmd()に対応する handle_scsi3_cmd()を作成してみた。
**handle_scsi_cmd()
[[ここ>http://www.linux.or.jp/JF/JFdocs/SCSI-Programming-HOWTO-8.html]]を参照
**handle_scsi3_cmd()
いい加減に実装しているので使い易いか分らないが、自分で必要と考えていた
INQUIRYとREAD ATTRIBUTEの供用として使えたので、まぁいいんだろう。
---(
#define SG_VERSION3 30000
int handle_cmd_sg3(
int fd,
unsigned char *cdb,
int cdblen,
int dxfer,
unsigned char *rbuf,
int rbuflen
) {
int ret, k, i;
sg_io_hdr_t sg_hdr;
sg_io_hdr_t *p = &sg_hdr;
int senselen = 0xffff;
unsigned char sense_buffer[senselen];
// SG_IOが使えるかチェックする前置き
if ( ioctl(fd, SG_GET_VERSION_NUM, &k) < 0 ||
k < SG_VERSION3 ) {
fprintf(stderr,
"unable to use this, bacause SG version is elder than %d\n",
SG_VERSION3);
return -1;
}
memset(p, 0, sizeof(sg_io_hdr_t));
p->interface_id = 'S';// required and fixed
p->cmd_len = cdblen;
p->cmdp = cdb;
// p->iovec_count = 0; vec ioする場合
p->dxfer_direction = dxfer;
/*
SG_DXFER_NONE SCSI test unit ready command
SG_DXFER_TO_DEV SCSI WRITE command
SG_DXFER_FROM_DEV SCSI READ command
SG_DXFER_TO_FROM_DEV use only relevant to indirect I/O
SG_DEXFER_UNKNOWN misc. For vendor specific.
*/
p->dxfer_len = rbuflen;
p->dxferp = rbuf;
p->mx_sb_len = sizeof(sense_buffer);
p->sbp = sense_buffer;
p->timeout = 10000;// timeout 10sec
//p->flags = 0;
//p->pack_id = 0;
//p->usr_ptr = NULL;
ret = ioctl(fd, SG_IO, p);
if ( ret == -1 ) {
fprintf(stderr, "ioctl(SG_IO) : %s[%d]\n", strerror(errno), errno);
return -1;
}
// handling response
if ( (p->info & SG_INFO_OK_MASK) != SG_INFO_OK ) {
// failure case
if ( p->sb_len_wr > 0 ) {
fprintf(stderr, "SENSE DATA: ");
for ( i = 0; i < p->sb_len_wr; i++ ) {
printf("0x%02x ", sense_buffer[i]);
}
printf("\n");
}
if ( p->masked_status )
printf("SCSI STATUS : 0x%x\n", p->status);
if ( p->host_status )
printf("HOST STATUS : 0x%x\n", p->host_status);
if ( p->driver_status )
printf("DRIVER STATUS : 0x%x\n", p->driver_status);
return -1;
}
return 0;
}
---)
*参考文献
Linuxの開発参考文献はonlineで必要なものは大体手に入る。
-SGドライバのドキュメント
--http://sg.torque.net/sg/p/sg_v3_ho.html
-Linux JFのSCSI機器用プログラミングHowTo
--http://www.linux.or.jp/JF/JFdocs/SCSI-Programming-HOWTO.html
--http://archive.linux.or.jp/JF/JFdocs/SCSI-Programming-HOWTO.html
-SCSIの仕様
--http://www.t10.org/drafts.htm
Last-modified: 2010-11-15 18:07:16