gpt4 book ai didi

c - 通过单个函数发送各种 scsi 命令

转载 作者:行者123 更新时间:2023-11-30 17:37:32 91 4
gpt4 key购买 nike

我一直在使用 scsi 命令,我可以发送一些基本命令,例如不同的查询等。

我一直在使用这个示例来生成我的查询。我正在努力使这个示例能够使用不同的 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;
}

最佳答案

我只是遇到了一个小问题。我的CDB错了!

我必须使用这个:

scsi_read_capacity.cmdblk[0]=0x9E;
scsi_read_capacity.cmdblk[1]=0x10;
scsi_read_capacity.cmdblk[13]=32;

第二个字节必须等于 0x10,这是因为 scsi cmd 0x9E 是一个服务操作命令,它接受第二个字节中定义其行为的参数!

关于c - 通过单个函数发送各种 scsi 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22367137/

91 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com