2

我是 SCSI CDB 编程的新手。我有一些使用 6 字节 CDB 为写入命令编写的代码

ccb = (Exec_IO_CCB *)(buffer + header_size);   
ccb->ccb_length = sizeof(Exec_IO_CCB);          
ccb->cam_opcode = 0x1;    
ccb->connect_id = 0;    
ccb->data_buf_ptr = (long)(header_size + ccb->ccb_length + MAX_SENSE_LEN);    
ccb->data_xfer_length = (long)(XFER_BUFSIZE - ccb->data_buf_ptr);    
ccb->sense_buf_ptr = (long)(header_size + ccb->ccb_length);    
ccb->sense_buf_length = MAX_SENSE_LEN;    
ccb->time_out = CAM_TIMEOUT;    
ccb->cdb_length = 6;    
ccb->cam_flags = DATA_OUT;    
ccb->cdb[0] = 0xA;   /*  0xA SCSI Opcode for write operation */    
ccb->cdb[1] = 0;    
ccb->cdb[2] = (ccb->data_xfer_length & 0xFF0000) >> 16;    
ccb->cdb[3] = (ccb->data_xfer_length & 0xFF00) >> 8;    
ccb->cdb[4] = (ccb->data_xfer_length & 0xFF);    
ccb->cdb[5] = 0;

从上面的代码我不明白 cdb[2] 和 cdb[3] 是如何派生的?

在类似的行中,我正在尝试为写入命令开发 10 字节 CDB。如何填写占LBA的cdb[2-5]的数据?

ccb->cam_flags = DATA_OUT;    
ccb->cdb[0] = 0x2A;     /*  0x2A SCSI Opcode for write10  CDB */    
ccb->cdb[1] = 0;    
ccb->cdb[2] =  ??    
ccb->cdb[3] =  ??    
ccb->cdb[4] =  ??    
ccb->cdb[5] =  ??    
ccb->cdb[6] = 0;    
ccb->cdb[7] = (ccb->data_xfer_length & 0xFF);    
ccb->cdb[8] = (ccb->data_xfer_length & 0xFF);    
ccb->cdb[9] = 0;
4

4 回答 4

0

要轻松形成 CDB 命令,您可以使用libscsicmd,它既可以形成 cdb,也可以解析 SCSI 回复的结果,例如检测缓冲区。它可能不包括我根据需要处理它时的所有命令和回复,但我会慢慢但肯定地处理事情。

于 2014-08-27T06:54:39.213 回答
0

查看 SCSI SBC 标准。这是草稿形式的 SBC-3,但 WRITE (6) 和 (10) 在相当长的一段时间内没有改变:http ://www.t10.org/ftp/t10/document.05/05-344r0.pdf 。

对于 WRITE (6),cdb[2] 和 cdb[3] 是逻辑块地址的低 16 位,而不是传输长度。传输长度是您要写入的块数。地址是设备上您要开始编写它们的位置。如果它位于磁盘的最开头,则为 LBA 0。如果设备有 512 字节的块,并且您想开始写入 1 MiB,则您的地址为 LBA 2048。

于 2013-08-21T15:18:11.993 回答
0

来看看http://en.wikipedia.org/wiki/SCSI_Write_Commands,很简单。

于 2013-08-22T08:40:10.950 回答
0

您不能将 2048 放入字节 5,因为字节 5 是一个字节,而 2048 是一个短字节。而是使用 cdb[4]=((2048 & 0xFF00) >> 8) 和 cdb[5]=(2048 & 0xFF)。同样对于 cdb[7],您已经分配了 data_xfer_length 的低位字节,但它应该是高位字节。

于 2013-08-26T15:29:48.103 回答