簡體   English   中英

傳輸長度超過1345時,Linux scsi ata cmd寫入或讀取有時可以工作,有時不起作用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM