2

I implemented some self-defined scsi commands in one usb device. One is: { 0xB1, 0xF5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }.

I use the following code to send this self-defined command to the usb device. The OS is ubuntu 14.04.

int main(int argc, char * argv[])
{
    int sg_fd, k, i;
    unsigned char readCmdBlk[READ_CMD_LEN] =
                { 0xB1, 0xF5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };

unsigned char readBuff[READ_REPLY_LEN];
unsigned char sense_buffer[32];
sg_io_hdr_t io_hdr;

if (2 != argc) {
    printf("Usage: 'sg_simple0 <sg_device>'\n");
    return 1;
}
if ((sg_fd = open(argv[1], O_RDWR)) < 0) {
    perror("error opening given file name");
    return 1;
}
if ((ioctl(sg_fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) {
    printf("%s is not an sg device, or old sg driver\n", argv[1]);
    return 1;
}
memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
io_hdr.interface_id = 'S';
io_hdr.cmd_len = sizeof(readCmdBlk);
io_hdr.mx_sb_len = sizeof(sense_buffer);
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
io_hdr.dxfer_len = READ_REPLY_LEN;
io_hdr.dxferp = readBuff;
io_hdr.cmdp = readCmdBlk;
io_hdr.sbp = sense_buffer;
io_hdr.timeout = 20000;     /* 20000 millisecs == 20 seconds */

if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
    perror("sg_simple0: Inquiry SG_IO ioctl error");
    return 1;
}

}

I use debugfs to capture the command sent out on the usb bus, and found that the command sent out is: { 0xB1, 0x15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }.

The second byte changed from 0xF5 to 0x15. By trying some other commands, I found that the first three bits of the second byte are always set as zero.

Why does ioctl change the command content when sending it out?

How can I make ioctl send exactly the same command as I defined?

hippietrail
  • 15,848
  • 18
  • 99
  • 158
Jesse
  • 21
  • 1

0 Answers0