2012-08-08 224 views
6

我嘗試向SSD發出scsi read(10)write(10)。我使用this example code作爲參考/基本代碼。SCSI讀取(10)和寫入(10)SCSI通用接口

這是我的SCSI閱讀:

#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寫:

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寫入)什麼的hexdumps讀取(SCSI讀)

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)),我也會得到相同的結果。

我認爲,我嘗試編寫的LBA可能被禁止寫入,並且我讀取了緩存。但是通過LBA地址從0x00-0xFF進行交換不會改變 - 這意味着我讀取了相同的數據(Abcdefg)。

您是否知道scsi讀取或寫入scsi通用接口的示例實現?

回答

4

在SCSI中,LBA的單位和傳輸長度是塊,有時稱爲扇區。這幾乎總是512字節。所以,你不能讀或寫32字節。至少,你必須做512個字節==一個塊。這一點是你需要解決的大部分問題。

您的傳輸長度在您的scsi_write實現中爲零,因此它實際上不會寫入任何數據。

您應該爲CDB和寫入/讀取數據使用不同的緩衝區。我懷疑這些緩衝區的混淆會導致你的實現寫過一個靜態分配的數組的末尾和你的ReadBuffer。在valgrind下運行它,看看出現了什麼。

最後,handle_scsi_cmd中的任何內容都會出錯。設置數據傳輸可能會非常棘手......特別是,確保您直接瞭解I/O頭的dxfer_direction中的數據進入方式:用於寫入的SG_DXFER_TO_DEV,用於讀取的SG_DXFER_FROM_DEV。

看看這個如何做一個讀(16)的例子。這更符合你正在努力完成的任務。

http://fossies.org/linux/misc/sg3_utils-1.33.tgz:a/sg3_utils-1.33/examples/sg_simple16.c

+0

非常感謝。 sg3_utils的例子幫助了我很多,現在它工作。 – samuirai 2012-08-13 13:04:01