创建SCSI 10字节CDB

时间:2013-08-21 05:40:32

标签: c scsi

我是SCSI CDB编程的新手。我使用6byte 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 Byte 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 个答案:

答案 0 :(得分: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.

答案 1 :(得分:0)

答案 2 :(得分:0)

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

答案 3 :(得分:0)

要轻松形成CDB命令,您可以使用libscsicmd它可以形成cdbs并解析SCSI回复的结果,例如感知缓冲区。它可能不包括所有的命令和回复,因为我需要它,但我会慢慢但确定地处理这些事情。