ioctl(SG_IO)工作,写/读对不

时间:2015-07-27 14:48:25

标签: c++ linux ioctl scsi

我正在尝试执行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

0 个答案:

没有答案