[英]Linux scsi ata cmd write or read sometimes work and sometimes didn't work when transfer length is over 1345
我的代碼如下:
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)
您沒有將SCSI CDB中的字節初始化為零,因此有時cmd[1]
, cmd[14]
和cmd[15]
存在垃圾。 在頂部添加對memset
的調用,或使用= { };
初始化數組= { };
。
另外,我知道很多示例都使用這種技術來初始化命令結構,但是,伙計,這確實會讓您發瘋。 我建議為使用位域的CDB定義__attribute__ ((packed))
結構。
最后,行cmd[2] = (lba >> 54) & 0xFF;
應該將lba
移位56位,而不是54位。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.