Linux SCSI read/write

This is a discussion on Linux SCSI read/write within the Linux Programming forums, part of the Platform Specific Boards category; Hi, I'm trying to read/write to specific sectors (512 bytes) in a SATA storage media(/dev/sda) using ioctl and some simple ...

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    4

    Linux SCSI read/write

    Hi,

    I'm trying to read/write to specific sectors (512 bytes) in a SATA storage media(/dev/sda) using ioctl and some simple SCSI read/write commands. I'm having some problems with consistency and just getting it to work. Here's what I've tried:

    Using read(10)/read(12), when I send the ioctl over to the device, instead of getting the 1st 512 bytes, I get some identification info instead. For example if the drive is a Toshiba drive I'd see the TOSHIBA and the model number, which is actually the ata ident information.

    When I use read(6) and send the ioctl, this seems to work for my HDD despite read(6)'s transfer length field being only 8 bytes. I guess the ioctl's transfer length overrides the SCSI CDB's transfer length? I don't know. Despite this, on some HDDs the io_hdr.info and io_hdr.masked_status is non-zero, which indicates a possible error?

    However, when I use read(6) to test on a USB memory stick, it gives me the ident information again instead of the 512byte sector.

    As for writes, I've only tried write(6) so far, but whenever I send the ioctl out, it would just hang there forever until I close the shell. I'm wondering what I'm doing wrong?

    My function (in this case reading a 512byte sector from LBA 0) is as follows:

    Code:
    int read_sector(const char *device_name, unsigned char *data)
      int fd, res;
      const int t_length = 512;              // 512 bytes transferred
      unsigned char rdCmdBlk6[SCSI_CDB6_LEN] = 
        { SCSI_READ6, // Command
          0, 0, 0, 0, 0 };
      unsigned char sense_b[SENSE_BUFF_LEN];
      sg_io_hdr_t io_hdr;
    
      // Open device
      fd = open(device_name, O_RDONLY);
    
      // Prepare SCSI READ (6) command
      rdCmdBlk6[1]  = 0x00;           // LBA
      rdCmdBlk6[2]  = 0x00;           // LBA
      rdCmdBlk6[3]  = 0x00;           // LBA
      rdCmdBlk6[4]  = t_length;       // transfer length
    
      // Prepare the sg_io_hdr_t structure
      memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
      io_hdr.interface_id = 'S';                  // Always set to 'S' for sg driver
      io_hdr.cmd_len = sizeof(rdCmdBlk6);         // Size of SCSI command
      io_hdr.mx_sb_len  = sizeof(sense_b);        // Max sense buffer size(for error)
      io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; // Data transfer direction(no data)
      io_hdr.dxfer_len = t_length;                // Data transfer length(512)
      io_hdr.dxferp = data;                       // Data transfer buffer(none)
      io_hdr.cmdp = rdCmdBlk6;                    // SCSI command buffer
      io_hdr.sbp = sense_b;                       // Sense buffer
      io_hdr.timeout = 5000;                      // Timeout(5s)
    
      // Sends the command to device
      if ((res = ioctl(fd, SG_IO, &io_hdr)) < 0) {
        close(fd);
        return -1;
      }
    
      // Error processing
      if ( ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) || // check info
           (io_hdr.masked_status != 0x00) ||                  // check status(0 if ioctl success)
           (io_hdr.msg_status != 0x00) ||                     // check message status
           (io_hdr.host_status != 0x00) ||                    // check host status
           (io_hdr.driver_status != 0x00) )                   // check driver status
      {
        close(fd);
        return -1;
      } else 
      {
        close(fd);
        return 0;
      }
    }
    The write_sector() code is similar except for appropriate changes in io_hdr and wrCmdBlk[].

    Anyone knows what's going on?

    Thanks!
    Last edited by galapogos; 12-09-2008 at 02:10 AM.

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,340
    > rdCmdBlk6[4] = t_length; // transfer length
    An int into a char - what do you think happens next?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Wireless Network Linux & C Testbed
    By james457 in forum Networking/Device Communication
    Replies: 3
    Last Post: 06-11-2009, 11:03 AM
  2. Linux SCSI programming
    By galapogos in forum Linux Programming
    Replies: 0
    Last Post: 12-01-2008, 02:37 AM
  3. Dabbling with Linux.
    By Hunter2 in forum Tech Board
    Replies: 21
    Last Post: 04-21-2005, 04:17 PM
  4. installing linux for the first time
    By Micko in forum Tech Board
    Replies: 9
    Last Post: 12-06-2004, 04:15 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21