使用SCSI通用接口的SCSI读取(10)和写入(10) [英] SCSI Read (10) and Write (10) with the SCSI Generic Interface

查看:745
本文介绍了使用SCSI通用接口的SCSI读取(10)和写入(10)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试发布scsi read(10)此示例代码作为参考/基本代码.

I try to issue a scsi read(10) and write(10) to a SSD. I use this example code as a reference/basic code.

这是我的scsi阅读:

This is my scsi read:

#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 | <- cmd
   * +------------------+
   * | copy of cmdblk   | <- 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));
}

这是我的scsi写道:

And this is my scsi write:

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 | <- cmd
   * +------------------+
   * | copy of cmdblk   | <- 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);
  }
}

在以下示例中,我做

  1. scsi已读
  2. scsi写
  3. scsi已读

然后我打印已写入(scsi写入)和已读取内容(scsi读取)的十六进制转储

And I print the hexdumps of the data which is written (scsi write) and what is read (scsi read)

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

再次运行这三个命令后,我应该首先阅读Abcdefg.正确的?但是再次运行它们不会改变任何事情.您现在可以假设,我使用的内存仍然具有以前功能的数据,但是即使在sys_read()发生之前运行memset(Readbuff,0,sizeof(Readbuff)),我也会得到相同的结果.

fter running the three commands again, I should read Abcdefg 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 memset(Readbuff,0,sizeof(Readbuff)) before the sys_read() happens.

我以为,我尝试写入的LBA可能被禁止写入,并且我读取了缓存.但是从0x00-0xFF对LBA地址进行插值不会产生任何变化-这意味着,我读取了相同的数据(Abcdefg).

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 (Abcdefg).

您知道使用scsi通用接口进行scsi读写的示例实现吗?

Do you know an example implementation of scsi read or writes with the scsi generic interface?

推荐答案

在SCSI中,LBA的单位和传输长度以块为单位,有时也称为扇区.这几乎总是512字节.因此,您不能只读取或写入32个字节.至少,您必须执行512字节==一个块.这一点是您需要修复的大部分内容.

In SCSI, the units of the LBA and the transfer length are in blocks, sometimes called sectors. This is almost always 512 bytes. So, you can't read or write just 32 bytes. At a minimum, you'll have to do 512 bytes == one block. This one point is most of what you need to fix.

在您的scsi_write实现中,您的传输长度为零,因此实际上不会写入任何数据.

Your transfer length is zero in your scsi_write implementation, so it's not actually going to write any data.

您应该为CDB和写入/读取数据使用不同的缓冲区.我怀疑关于这些缓冲区的困惑会导致您的实现在静态分配的数组之一的末尾和ReadBuffer上进行写操作.在 valgrind 下运行它,然后查看显示的内容.

You should use different buffers for the CDB and the write/read data. I suspect that confusion about these buffers is leading your implementation to write past the end of one of your statically-allocated arrays and over your ReadBuffer. Run it under valgrind and see what shows up.

最后,handle_scsi_cmd中的任何内容都可能出错.设置数据传输可能很棘手……特别是,请确保直接在I/O标头的dxfer_direction中确定数据的传输方式:SG_DXFER_TO_DEV用于写入,SG_DXFER_FROM_DEV用于读取.

And lastly, a lot could go wrong in whatever is in handle_scsi_cmd. It can be tricky to set up the data transfer... in particular, make sure you're straight on which way the data is going in the I/O header's dxfer_direction: SG_DXFER_TO_DEV for write, SG_DXFER_FROM_DEV for read.

查看此示例以了解如何执行read(16).这更符合您要完成的工作.

Check out this example of how to do a read(16). This is more along the lines of what you're trying to accomplish.

https://github.com/hreinecke/sg3_utils/blob /master/examples/sg_simple16.c

这篇关于使用SCSI通用接口的SCSI读取(10)和写入(10)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆