我正在写一个小的c程序,通过
ioctl(int fd, long int request, &io_buf)
但经过多次尝试和错误之后,ioctl返回
-1
,并返回errno消息“Invalid Argument”我在Linux上,以sudo的身份运行我的程序。我要向其发出请求的设备是一个通过SCSI连接的光盘驱动器。我尝试过磁带状态并通过将请求(分别为
MTIOCGET
或MTIOCTOP
)传递到ioctl
来查找请求。磁带状态函数的代码段,其中fd是open()返回的设备的文件描述符,mtgetbuf是
sys/mtio.h
中mtget struct的实例 stat = ioctl(fd, MTIOCGET, &mtgetbuf);
if (stat == -1)
{
perror("error on ioctl MTIOCGET request: ")
return EXIT_FAILURE;
}
seek tape函数的类似代码片段,除了
mtopbuf
是mtop结构的一个实例,MTSEEK是seek操作的定义操作代码,也在sys/mtio.h
中 mtopbuf.mt_op = MTSEEK;
stat = ioctl(fd, MTIOCTOP, &mtopbuf);
if (stat == -1)
{
perror("error on ioctl MTIOCGET request: ")
return EXIT_FAILURE;
}
与无效参数错误消息和返回-1不同,我希望ioctl和相应的结构实例mtgetbuf和mtopbuf成功返回,让它们的成员填充设备提供的数据。
也就是说,带有
ioctl()
请求的成功MTIOCGET
命令将向mtgetbuf mt戋u类型成员返回MT_ISSCSI1
、MT_ISSCSI2
或MT_ISUNKNOWN
的值(我不认为它是其他特定于供应商的设备的任何其他定义值)。注意:我知道
linux/mtio.h
头文件,我尝试用它代替sys/mtio.h
但结果是一样的。 最佳答案
我最近成功地使用SCSI通用Linux驱动程序(SG)向块设备发出了请求。有三个头文件(如下)提供了操作码、用于从设备传递和检索数据的结构以及其他信息。
SCSI SG头文件:
/usr/include/scsi/scsi.h
/usr/include/scsi/scsi_ioctl.h
/usr/include/scsi/sg.h
在线资源的组合有助于理解如何打包、发送和接收请求:
1)TLDP SCSI Generic(sg)HOW-TO guide是通过sg驱动程序与SCSI设备通信的信息字体。提供了指向它的链接here。它详细说明了可以发出的各种命令,如何通过创建sg_io_hdr_t结构的实例来打包命令,以及发送SCSI查询命令(返回设备的基本供应商信息)的programming example。还有用于错误处理和理解不成功SCSI请求的状态和检测代码。
2)Seagate的SCSI命令参考手册有时有助于理解SCSI命令中字节/位的结构。通常,操作码占用第一个字节,其余字节为零。本参考手册中的操作代码是在上述三个头文件之间定义的。
我已经能够发送成功的查询和获得_SG_版本号请求,并且很可能已经能够发送SEEK(6)、READ_CAPACITY(10)和REZERO_UNIT命令。我之所以这么说,很可能是因为没有返回-1/errno值,也没有将任何信息传递回表示警告/错误(SCSI、主机适配器或驱动程序状态代码)的检测缓冲区。
希望这能回答OPs的问题。