我正在写一个小的c程序,通过

        ioctl(int fd, long int request, &io_buf)

但经过多次尝试和错误之后,ioctl返回-1,并返回errno消息“Invalid Argument”
我在Linux上,以sudo的身份运行我的程序。我要向其发出请求的设备是一个通过SCSI连接的光盘驱动器。我尝试过磁带状态并通过将请求(分别为MTIOCGETMTIOCTOP)传递到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_ISSCSI1MT_ISSCSI2MT_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的问题。

09-07 10:01