我是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;
答案 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回复的结果,例如感知缓冲区。它可能不包括所有的命令和回复,因为我需要它,但我会慢慢但确定地处理这些事情。