ioctl使用SCSI传递

时间:2013-02-10 14:34:28

标签: c++ c linux scsi

使用Windows我可以使用以下简化代码轻松与USB设备通信:

DWORD dwJunk;    // discard results from DeviceIOControl()
int   iReply;
char  cBuffer[100];
// cBuffer is initialized here.
HANDLE hDevice; // handle to the drive to be examined 
CString sDrive = _T(\\\\.\\H:); // drive H: for this test
hDevice = CreateFile(sDrive,            // drive to open
   GENERIC_READ | GENERIC_WRITE,        // read and write access to the drive
   FILE_SHARE_READ | FILE_SHARE_WRITE,  // share mode           
   NULL,                                // default security attributes
   OPEN_EXISTING,                       // disposition
   0,                                   // file attributes
   NULL);                               // do not copy file attributes

iReply = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &cBuffer, sizeof(cBuffer), &cBuffer, sizeof(cBuffer), &dwJunk, (LPOVERLAPPED)NULL);

我正在尝试在linux中做同样的事情,但是无法找出ioctrl()参数,或者更好地放置结构。我们非常感谢代码片段。感谢。

3 个答案:

答案 0 :(得分:1)

不幸的是,我使用您的链接修改的代码没有返回任何结果。这是我使用的剥离代码。 ioctl()返回时没有错误:

#define DEF_TIMEOUT 5000 // 5 seconds
char cDiskName[] = "/dev/sg3";
int fd = open(cDiskName, O_RDWR);
if (fd < 0)
{
  printf("Open error: %s, errno=%d (%s)\n", cDiskName, errno, strerror(errno));
  return 1;
}

unsigned char turCmbBlk[] = {0x00, 0, 0, 0, 0, 0};
struct sg_io_hdr io_hdr;

unsigned char cIOBuffer[100];

// buffer initialization code omitted

memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
io_hdr.interface_id = 'S';
io_hdr.cmd_len = sizeof(turCmbBlk);
io_hdr.mx_sb_len = sizeof(cIOBuffer);
io_hdr.dxfer_direction = SG_DXFER_NONE;
io_hdr.cmdp = turCmbBlk;
io_hdr.sbp = cIOBuffer;
io_hdr.timeout = DEF_TIMEOUT;
if (ioctl(fd, SG_IO, &io_hdr) < 0)
{
  printf("ioctl error: errno=%d (%s)\n", errno, strerror(errno));
}

// Code returned here without any errors but cIOBuffer remains unchanged.

也许电话需要不同的请求代码?

答案 1 :(得分:1)

以下是更多文档:

答案 2 :(得分:0)

见这里:

#include <sys/ioctl.h>

int ioctl(int d, int request, ...); 

<强>参数:

  1. Filedescriptor (必须打开!)
  2. 请求代码号码(取决于设备)
  3. 无内存指针到内存(进入/来自驱动程序)
  4. 示例

    #include <stdio.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <sys/ioctl.h>
    #include <linux/usbdevice_fs.h>
    
    void main(int argc, char **argv)
    {
        const char *filename;
        int fd;
    
        filename = argv[1];
    
        fd = open(filename, O_WRONLY);
        ioctl(fd, USBDEVFS_RESET, 0);
    
        close(fd);
    
        return;
    }
    

    <强>文档


    修改

    #define BUFF_SIZE 100 // - Buffersize
    
    #define DEF_TIMEOUT 5000 // 5 seconds
    char cDiskName[] = "/dev/sg3";
    int fd = open(cDiskName, O_RDWR);
    if (fd < 0)
    {
      printf("Open error: %s, errno=%d (%s)\n", cDiskName, errno, strerror(errno));
      return 1;
    }
    
    unsigned char turCmbBlk[] = {0x00, 0, 0, 0, 0, 0};
    struct sg_io_hdr *p = (struct sg_io_hdr *) malloc(sizeof(struct sg_io_hdr)); // - dynamic memory allocation - free() required somewhere
    
    unsigned char cIOBuffer[BUFF_SIZE];
    unsigned char replyBuffer[BUFF_SIZE]; // - dxfer buffer
    
    // buffer initialization code omitted
    
    memset(p, 0, sizeof(struct sg_io_hdr));
    p->interface_id = 'S';
    p->cmd_len = sizeof(turCmbBlk);
    p->mx_sb_len = BUFF_SIZE;
    p->dxfer_direction = SG_DXFER_NONE;
    p->cmdp = turCmbBlk;
    p->sbp = cIOBuffer;
    p->timeout = DEF_TIMEOUT;
    p->flags = SG_FLAG_DIRECT_IO; // - Does this help?
    p->dxferp = replyBuffer; // - Set dxferp buffer - (A)
    p->dxfer_len = BUFF_SIZE; // - buffersize
    
    if (ioctl(fd, SG_IO, p) < 0)
    {
      printf("ioctl error: errno=%d (%s)\n", errno, strerror(errno));
    }
    
    // Code returned here without any errors but cIOBuffer remains unchanged.
    

    注意(A):请尝试设置您在此处使用的输入/输出缓冲区。

    <强>文档