【问题标题】:Linux scsi ata cmd write or read sometimes work and sometimes didn't work when transfer length is over 1345当传输长度超过 1345 时,Linux scsi ata cmd 写入或读取有时有效,有时无效
【发布时间】:2019-10-26 16:53:30
【问题描述】:

我的代码如下:

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);

如果我发送超过 1345 的 cmd 传输长度,它有时会工作,有时它不会工作。如果传输长度增加,不工作的部分也会增加。 cmd 不工作时没有 uart 日志或内核日志。

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

【问题讨论】:

    标签: linux command scsi sata ata


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢你,但是当我尝试你的评论时它不起作用......我不知道为什么命令有时会进入设备,有时不能......
    猜你喜欢
    • 2013-03-17
    • 2022-11-16
    • 1970-01-01
    • 2011-01-27
    • 2023-03-09
    • 2012-09-01
    • 1970-01-01
    • 2015-02-11
    • 2012-08-02
    相关资源
    最近更新 更多