Я пытаюсь выполнить команду запроса 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
Задача ещё не решена.