簡體   English   中英

發送 ATA 命令“使用 SAT(SCSI ATA 轉換)讀取本機最大地址(0x27、0xF8)不響應 SAS controller

[英]Sending ATA command "Read native max address (0x27 , 0xF8) not reponding over SAS controller using SAT(SCSI ATA translate)

我想通過 SAS 接口找出硬盤的本機最大地址。 我正在使用帶有 SCSI_PASS_THROUGH 的 SAT(scsi ata 翻譯)。

但無法從驅動器中使用 IOCTL_SCSI_PASS_THROUGH 找到 SCSI_PASS_THROUGH 的任何緩沖區或有效 senseinfo。 SCSI_PASS_THROUGH 的 cdb 值 =

sptwb.Spt.CdbLength = 12;
        sptwb.Spt.Cdb[0] = 0xA1;//ATA PASS THROUGH(12) OPERATION CODE(A1h)
        sptwb.Spt.Cdb[1] = (4 << 1) | 0; 
        sptwb.Spt.Cdb[2] = (1 << 3) | (1 << 2) | 2;
        sptwb.Spt.Cdb[3] = 0xe0;
        sptwb.Spt.Cdb[4] = 0x00;
        sptwb.Spt.Cdb[5] = 0x00;
        sptwb.Spt.Cdb[6] = 0x00;
        sptwb.Spt.Cdb[7] = 0x00;
        sptwb.Spt.Cdb[8] = (UCHAR)0x40;//(UCHAR)head;
        sptwb.Spt.Cdb[9] = 0x27;//COMMAND

但不返回任何緩沖區。 請提供准確的 cdb 參數以讀取 SAS 機器上的本機最大地址。

我面前沒有所有相關的 SCSI 規范。 因此,我假設您正在正確構建 SATL (SCSI ATA 轉換層) CDB。 首先要檢查的是 ioctl 是否已完成。 即,檢查DeviceIoControl()的返回代碼是否為TrueFalse ,然后檢查GetLastError()以確定發生了什么問題(如果適用)。 如果 ioctl 正常,請檢查SCSI_PASS_THROUGH_DIRECT 結構成員.ScsiStatus 如果這是 0,那么命令完成就好了。 如果狀態為 0,這很可能是沒有有效意義信息的原因。

當我偶然發現這個線程時,我實際上正在研究這個命令。 最新的 ATA 命令規范 ACS-3(日期為 2013 年 10 月 28 日)顯示讀取本機最大地址讀取本機最大地址擴展命令現已過時。 我在 ACS-2 中找到了他們的定義。 日期為 2009 年 8 月 3 日的最新草案表明該命令的輸出不會是緩沖區。 相反,輸出將在返回的Device-To-Host FIS的 LBA 字段中。


附錄原帖的措辭讓我相信這是在 Windows 中完成的。 我應該包括該過程對於 Linux 是相同的,如果這是您使用的。 但是,不要使用GetLastError()來確定出了什么問題。 在 Linux 中, ioctl()的返回碼將是您需要的代碼。

如果在 Linux 中,您很可能使用sg驅動程序和sg_io_hdr_t 結構 該結構還有一個.status成員,其中包含 SCSI 狀態代碼。 無論是在 Linux 還是 Windows 中,您都應該始終檢查此代碼,因為假設命令成功是因為 ioctl 所做的是一種謬論。 Linux 中還有其他可用的直通驅動程序,例如 LSI MPT 接口。 如果這是您正在使用的,則過程仍然相同。

您嘗試執行的命令 0xF8(讀取本機最大地址)不是 SCSI 命令,而是 ATA 命令。

CDB 代碼 0xA1 確實與 IOCTL_SCSI_PASS_THROUGH API 一起使用,以將 SCSI/ATAPI 命令發送到設備。 但這不是你想要的。

改為嘗試IOCTL_ATA_PASSTHROUGH

此處的示例和討論:將ATA 命令直接發送到 Windows 中的設備?

我想這就是你想要的:
這在安裝了“sg3_utils”的 cygwin 或本機 linux 下工作。

#!/bin/bash
dev=$1
sz=$(sg_raw 2>/dev/null -r 40 $dev 9e 10 00 00 00 00 00 00 00 00 00 00 00 0c 00 00 -b|xxd -p)
nb=$((0x${sz:0:16}+1))
bs=$((0x${sz:16:8}))
pbs=$((bs*2**0x${sz:24:4}))
echo Real number of blocks: $nb
echo Real HDD Size: $((nb*bs))
echo Logical Block Size: $bs
echo Physical Block Size: $pbs
p=$((0x$(sg_raw 2>/dev/null $dev -r 512 85 08 0e 00 00 00 01 00 00 00 00 00 00 00 ec 00 -o -|xxd -c 0 -ps|while read -N1 a;do read -N1 b;echo -n $b$a;done|cut -c 401-416|rev)))
echo User Addressable blocks: $p
echo User Addressable size: $(($p*bs))
./gethdsize.sh PD2 (device obtained with sg_scan)  

output:

Real number of blocks: 27344764928
Real HDD Size: 14000519643136
Logical Block Size: 512
Physical Block Size: 4096
User Addressable blocks: 27344750581
User Addressable size: 14000512297472

將驅動器重置為最大 lba 后:

Real number of blocks: 27344764928
Real HDD Size: 14000519643136
Logical Block Size: 512
Physical Block Size: 4096
User Addressable blocks: 27344764928
User Addressable size: 14000519643136

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM