我正在尝试执行scsi查询命令。 我设法做到了:
device_ = open(device_path, O_RDWR|O_NONBLOCK);
...
if (ioctl(device, SG_IO, &io_hdr) < 0)
{
int err = errno;
cerr << "Inquiry SG_IO ioctl error. Errno: " << err <<
"; error message: " << strerror(err) << endl;
result = false;
}
我应该如何重写代码以使用写/读对?
SG_IO是一个阻塞操作,它会忽略O_NONBLOCK
标志,我需要确保该呼叫不会阻塞。
我使用这些文章作为参考:
http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/write.html http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/read.html
...并编写了这样的代码:
sg_io_hdr_t io_hdr, out_io_hdr;
do
{
size_t count = sizeof(sg_io_hdr_t);
size_t written = write(device, &io_hdr, count);
if (written == count)
{
break;
}
int err = errno;
cerr << "write io_hdr_t. Errno: " << err << "; error message: " << strerror(err) << endl;
if (err != EAGAIN)
{
return false;
}
} while (true);
do
{
size_t count = sizeof(sg_io_hdr_t);
// same result with both io_hdr and out_io_hdr as a second parameter
size_t read_count = read(device, &out_io_hdr, count);
if (read_count == count)
{
break;
}
int err = errno;
cerr << "write io_hdr_t. Errno: " << err << "; error message: " << strerror(err) << endl;
if (err != EAGAIN)
{
return false;
}
} while (true);
但是这段代码导致状态字段和意义缓冲区中的垃圾:
INQUIRY sense data length: 100
inquiry sense buffer (hex):
e4 9a eb 2a 30 fa de 2a 20 0
0 0 40 91 e6 2a d8 c3 e0 2a
40 5 f3 2a 14 38 e6 2a 14 38
e6 2a 0 0 0 0 3 0 0 0
0 0 0 0 1 0 0 0 b4 eb
b1 7f 1 0 0 0 e8 4e e6 2a
b8 eb b1 7f 0 0 41 0 5c ec
b1 7f 78 3c 40 0 2b 0 0 0
14 38 e6 2a 34 eb b1 7f 0 0
0 0 0 0 0 0 2 0 0 0
INQUIRY SCSI status=0xfe
masked_status=0x13
INQUIRY host_status=0x3f47
INQUIRY driver_status=0x93c8