title: SCSI Read (10) and Write (10) with the SCSI Generic Interface
body: <p>I try to issue a scsi <a href="http://en.wikipedia.org/wiki/SCSI_Read_Commands#Read_.2810.29">read(10)</a> and <a href="http://en.wikipedia.org/wiki/SCSI_Write_Commands#Write_.2810.29">write(10)</a> to a SSD. I use <a href="http://tldp.org/HOWTO/SCSI-Generic-HOWTO/pexample.html">this example code</a> as a reference/basic code.</p>
  
  <p>This is my scsi read:</p>
  
  <pre class="lang-c prettyprint-override"><code>#define READ_REPLY_LEN 32
  #define READ_CMDLEN 10
  void scsi_read()
  {
    unsigned char Readbuffer[ SCSI_OFF + READ_REPLY_LEN ];
    unsigned char cmdblk [ READ_CMDLEN ] =
        {        0x28,  /* command */
                    0,  /* lun/reserved */
                    0,  /* lba */
                    0,  /* lba */
                    0,  /* lba */
                    0,  /* lba */
                    0,  /* reserved */
                    0,  /* transfer length */
       READ_REPLY_LEN,  /* transfer length */
                    0 };/* reserved/flag/link */
    memset(Readbuffer,0,sizeof(Readbuffer));
    memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );
  
    /*
     * +------------------+
     * | struct sg_header | &lt;- cmd
     * +------------------+
     * | copy of cmdblk   | &lt;- cmd + SCSI_OFF
     * +------------------+
     */
  
    if (handle_scsi_cmd(sizeof(cmdblk), 0, cmd,
                        sizeof(Readbuffer) - SCSI_OFF, Readbuffer )) {
        fprintf( stderr, "read failed\n" );
        exit(2);
    }
    hex_dump(Readbuffer,sizeof(Readbuffer));
  }
  </code></pre>
  
  <p>And this is my scsi write:</p>
  
  <pre class="lang-c prettyprint-override"><code>void scsi_write ( void )
  {
    unsigned char Writebuffer[SCSI_OFF];
    unsigned char cmdblk [] =
        {        0x2A,  /* 0: command */
                    0,  /* 1: lun/reserved */
                    0,  /* 2: LBA */
                    0,  /* 3: LBA */
                    0,  /* 4: LBA */
                    0,  /* 5: LBA */
                    0,  /* 6: reserved */
                    0,  /* 7: transfer length */
                    0,  /* 8: transfer length */
                    0 };/* 9: control */
  
    memset(Writebuffer,0,sizeof(Writebuffer));
    memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );
    cmd[SCSI_OFF+sizeof(cmdblk)+0] = 'A';
    cmd[SCSI_OFF+sizeof(cmdblk)+1] = 'b';
    cmd[SCSI_OFF+sizeof(cmdblk)+2] = 'c';
    cmd[SCSI_OFF+sizeof(cmdblk)+3] = 'd';
    cmd[SCSI_OFF+sizeof(cmdblk)+4] = 'e';
    cmd[SCSI_OFF+sizeof(cmdblk)+5] = 'f';
    cmd[SCSI_OFF+sizeof(cmdblk)+6] = 'g';
    cmd[SCSI_OFF+sizeof(cmdblk)+7] = 0;
    /*
     * +------------------+
     * | struct sg_header | &lt;- cmd
     * +------------------+
     * | copy of cmdblk   | &lt;- cmd + SCSI_OFF
     * +------------------+
     * | data to write    | 
     * +------------------+
     */
  
    if (handle_scsi_cmd(sizeof(cmdblk), 8, cmd, 
                        sizeof(Writebuffer) - SCSI_OFF, Writebuffer )) {
        fprintf( stderr, "write failed\n" );
        exit(2);
    }
  }
  </code></pre>
  
  <p>In the following example I do</p>
  
  <ol>
  <li>scsi read</li>
  <li>scsi write</li>
  <li>scsi read</li>
  </ol>
  
  <p>And I print the hexdumps of the data which is written (scsi write) and what is read (scsi read)</p>
  
  <pre><code>Read(10)
  [0000]   00 00 00 44 00 00 00 44   00 00 00 00 00 00 00 00   ...D...D ........
  [0010]   00 2C 00 00 00 00 00 00   00 00 00 00 00 00 00 00   ........ ........
  [0020]   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   ........ ........
  [0030]   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   ........ ........
  [0040]   00 00 00 00                                         ....
  
  Write(10):
  [0000]   00 00 00 00 00 00 00 24   00 00 00 00 00 00 00 00   ........ ........
  [0010]   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   ........ ........
  [0020]   00 00 00 00 2A 00 00 00   00 00 00 00 00 00 41 62   ........ ......Ab
  [0030]   63 64 65 66 67 00                                   cdefg.
  
  Read(10):
  [0000]   00 00 00 44 00 00 00 44   00 00 00 00 00 00 00 00   ...D...D ........
  [0010]   04 00 20 00 70 00 02 00   00 00 00 0A 00 00 00 00   ....p... ........
  [0020]   04 00 00 00 41 62 63 64   65 66 67 00 00 00 00 00   ....Abcd efg.....
  [0030]   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   ........ ........
  [0040]   00 00 00 00                                         ....
  </code></pre>
  
  <p>fter running the three commands again, I should read <code>Abcdefg</code> with the first read. Right? But running them again changes nothing. You could now assume, that the memory I use has still the data from previous funcions, but I get the same result even though I run <code>memset(Readbuff,0,sizeof(Readbuff))</code> before the <code>sys_read()</code> happens.</p>
  
  <p>I assumed, that the LBA I try to write is maybe forbidden to write, and I read the cache. But interating over LBA Adresses from 0x00-0xFF changes nothing - That means, I read the same data (<code>Abcdefg</code>).</p>
  
  <p>Do you know an example implementation of scsi read or writes with the scsi generic interface?</p>