ioctrl с использованием 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 (), или лучше поставить структуру. Фрагмент кода будет очень признателен. Благодарю.

2

Решение

К сожалению, код, который я изменил по вашей ссылке, не дал никаких результатов. Вот раздетый код, который я использовал. 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

Посмотреть здесь:

#include <sys/ioctl.h>

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

Параметры:

  1. FileDescriptor (должен быть открыт!)
  2. Код заявки номер (зависит от устройства)
  3. Нетипизированный указатель в память (собирается / приходит от водителя)

пример

#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.

Примечание (А): Пожалуйста, попробуйте установить буфер ввода / вывода, с которым вы работаете, здесь.

Документация:

0
По вопросам рекламы [email protected]