我一直在玩scsi命令,我可以发送一些基本命令,如不同的inquirys等。
我一直用这个例子来生成我的查询。我正在努力使这个示例使用不同的scsi命令。
http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/pexample.html
我已经更改为通过结构接受不同的scsi命令的函数,它还返回基于输出的结构。这完美地适用于调查。但是,如果我发送READ CAPACITY(16)命令,则函数会在if语句中触发:
(io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK)
我是scsi编程的新手,所以我可能会做一些完全错误的事情......
我的READ CAPACITY(16)命令就是这样:
scsi_read_capacity.cmdblk[0]=0x9e;
scsi_read_capacity.cmdblk[13]=32;
CDB的其余部分为0!
这是代码:
#include <stdio.h>
#include <sys/ioctl.h>
#include <scsi/sg.h>
/* global struct to store return data from a scsi cmd*/
typedef struct SCSI_data {
unsigned char data[1024];
unsigned char raw_sens[252];
unsigned char sense_key;
unsigned char additional_sense_code;
unsigned char additional_sense_qualifier;
unsigned char additional_sense_length;
unsigned char sense_data_descriptors[10][244];
int result;
} SCSI_data;
/* global struct to store return data from a scsi cmd*/
typedef struct SCSI_cmd {
int sg_fd;
unsigned char cmdblk[32];
int cmdblklength;
int allocation_length;
int xfer;
int timeout;
} SCSI_cmd;
SCSI_data send_scsicmd(SCSI_cmd cmdobject) {
int k;;
unsigned char inqBuff[cmdobject.allocation_length];
unsigned char sense_buffer[252];
SCSI_data output_data;
sg_io_hdr_t io_hdr;
/* Prepare INQUIRY command */
memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
io_hdr.interface_id = 'S';
io_hdr.cmd_len = cmdobject.cmdblklength;
io_hdr.mx_sb_len = sizeof(sense_buffer);
io_hdr.dxfer_direction = cmdobject.xfer;
io_hdr.dxfer_len = cmdobject.allocation_length;
io_hdr.dxferp = inqBuff;
io_hdr.cmdp = cmdobject.cmdblk;
io_hdr.sbp = sense_buffer;
io_hdr.timeout = cmdobject.timeout;
if (ioctl(cmdobject.sg_fd, SG_IO, &io_hdr) < 0) {
output_data.result=2;
return output_data;
}
/* now for the error processing */
if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) {
output_data.result=1;
if (io_hdr.sb_len_wr > 0) {
printf("INQUIRY sense data: ");
for (k = 0; k < io_hdr.sb_len_wr; ++k) {
if ((k > 0) && (0 == (k % 10)))
printf("\n ");
printf("0x%02x ", sense_buffer[k]);
}
printf("\n");
}
if (io_hdr.masked_status)
printf("INQUIRY SCSI status=0x%x\n", io_hdr.status);
if (io_hdr.host_status)
printf("INQUIRY host_status=0x%x\n", io_hdr.host_status);
if (io_hdr.driver_status)
printf("INQUIRY driver_status=0x%x\n", io_hdr.driver_status);
}
else { /* assume INQUIRY response is present */
output_data.result=0;
for (k=0;k<cmdobject.allocation_length;k++) {
output_data.data[k]=inqBuff[k];
}
}
return output_data;
}
int main(int argc, char * argv[]) {
FILE *driveptr=fopen(argv[1], "r");
int i;
SCSI_data scsi_data_read_capacity;
SCSI_cmd scsi_read_capacity;
scsi_read_capacity.sg_fd=fileno(driveptr);
scsi_read_capacity.cmdblk[0]=0x9e;
scsi_read_capacity.cmdblk[13]=32;
scsi_read_capacity.cmdblklength=16;
scsi_read_capacity.xfer=SG_DXFER_FROM_DEV;
scsi_read_capacity.allocation_length=32;
scsi_read_capacity.timeout=1000;
scsi_data_read_capacity=send_scsicmd(scsi_read_capacity);
if (scsi_data_read_capacity.result==0) {
printf(" capacity in blocks: %02x%02x%02x%02x%02x%02x%02x%02x\n",
scsi_data_read_capacity.data[0],
scsi_data_read_capacity.data[1],
scsi_data_read_capacity.data[2],
scsi_data_read_capacity.data[3],
scsi_data_read_capacity.data[4],
scsi_data_read_capacity.data[5],
scsi_data_read_capacity.data[6],
scsi_data_read_capacity.data[7]);
printf(" blocksize: %02x%02x%02x%02x\n",
scsi_data_read_capacity.data[8],
scsi_data_read_capacity.data[9],
scsi_data_read_capacity.data[10],
scsi_data_read_capacity.data[11]);
}
fclose(driveptr);
return 0;
}
答案 0 :(得分:0)
我只是一个小问题。我的CDB错了!
我必须使用它:
scsi_read_capacity.cmdblk[0]=0x9E;
scsi_read_capacity.cmdblk[1]=0x10;
scsi_read_capacity.cmdblk[13]=32;
第二个字节必须等于0x10,这是因为scsi cmd 0x9E是一个服务操作命令,它在第二个字节中接受一个定义其行为的参数!