传输长度超过1345时,Linux scsi ata cmd写入或读取有时可以工作,有时不起作用

时间:2019-06-12 08:26:34

标签: linux command scsi sata ata

我的代码如下:

unsigned char cmd[16];
cmd[0] = WRITE_16;
//lba is start address
cmd[2] = (lba >> 54) & 0xFF;
cmd[3] = (lba >> 48) & 0xFF;
cmd[4] = (lba >> 40) & 0xFF;
cmd[5] = (lba >> 32) & 0xFF;
cmd[6] = (lba >> 24) & 0xFF;
cmd[7] = (lba >> 16) & 0xFF;
cmd[8] = (lba >> 8) & 0xFF;
cmd[9] = lba & 0xFF;
//len is transfer length
cmd[10] = (len >> 24) & 0xFF;
cmd[11] = (len >> 16) & 0xFF;
cmd[12] = (len >> 8) & 0xFF;
cmd[13] = len & 0xFF;

void* buffer;
buffer = malloc(len*512);
__u64 buffer_len = 512*len;
io_hdr.interface_id = 'S';
io_hdr.cmd_len = sizeof(cmd);
io_hdr.mx.sb_len = sizeof(sense);
io_hdr.dxfer_direction = SG_DXFER_TO_FROM_DEV;
io_hdr.dxfer_len = buffer_len;
io_hdr.dxferp = buffer;
io_hdr.cmdp = cmd;
io_hdr.sbp = sense;
io_hdr.timeout = 30000;
ioctl(fd, SG_IO, &io_hdr);

如果我发送的cmd传输长度超过1345,则有时可以正常工作,有时不能正常工作。如果传输长度增加,则无效的部分也会增加。当cmd不起作用时,没有uart日志或内核日志。

ps。如果cmd不起作用,则errno说22(invalid argument)

1 个答案:

答案 0 :(得分:0)

您没有将SCSI CDB中的字节初始化为零,因此有时cmd[1]cmd[14]cmd[15]中会有垃圾。在顶部添加对memset的调用,或使用= { };初始化数组。

此外,我知道很多示例都使用这种技术来初始化命令结构,但是,伙计,这确实会让您发疯。我建议为使用位域的CDB定义一个__attribute__ ((packed))结构。

最后,第cmd[2] = (lba >> 54) & 0xFF;行应将lba移位56位,而不是54位。