scsi READ CAPACITY (10)命令总结

READ CAPACITY (10)概述:

READ CAPACITY(10)命令(参见表119)请求设备服务器将描述直接访问块设备的容量和介质格式的8字节参数数据传输到数据缓存中。这个命令可以被处理,就好像它有一个HEAD OF QUEUE任务属性。
如果逻辑单元支持保护信息,应用客户端应使用READ CAPACITY(16)命令,而不应使用theREAD CAPACITY(10)命令。
在这里插入图片描述
For the definition of the LOGICAL BLOCK ADDRESS field see 2.2.3.

LOGICAL BLOCK ADDRESS field

这个领域已经被T10委员会宣布过时了。但是,包含它是因为它可能在某些产品上实现。如果PMI位设置为零,则逻辑块地址字段设置为零。如果PMI位设置为零,并且LOGICAL BLOCK ADDRESSfield不设置为零,则设备服务器将以CHECK CONDITION状态终止命令,并将感测键设置为ILLEGALREQUEST,并将附加感测码设置为INVALID FIELD IN CDB。

PMI (Partial Medium Indicator) bit

这一点已经被T10委员会宣布过时了。但是,包含它是因为它可能在某些产品上实现
0:部分介质指示器(PMI)位设置为零表示设备服务器返回直接访问块设备上最后一个逻辑块的信息。
1:PMI位设置为1指定设备服务器在遇到供应商特定的数据传输延迟之前返回逻辑块之后的最后一个逻辑块的信息。

此函数旨在帮助存储管理软件确定是否有足够的空间从CDB中指定的逻辑块地址开始包含频繁访问的数据结构(例如,文件目录或文件索引),而不会引起额外延迟。赔率。

READ CAPACITY (10) parameter data(返回的数据格式)

READ CAPACITY(10)参数数据定义在表120中。每当READ CAPACITY(10)参数数据发生变化时,设备服务器应建立一个如SBC-4所述的单位关注条件。

RETURNED LOGICAL BLOCK ADDRESS field

如果逻辑块的数量超过了能够在RETURNED logical BLOCK ADDRESS字段中指定的最大值,设备服务器应该将RETURNED logical BLOCK ADDRESS字段设置为FFFFFFFFh。然后,应用程序客户端应该发出READ CAPACITY(16)命令(参见3.24)来检索READ CAPACITY(16)参数数据。
在这里插入图片描述
0:如果PMI位设置为零,则设备服务器将RETURNED LOGICAL BLOCK ADDRESS字段设置为以下值中的较低值:
a)直接存取块设备上最后一个逻辑块的LBA;or
b) FFFFFFFFh。

1:如果PMI位设置为1,则设备服务器应将返回的逻辑块地址字段设置为以下几项中的较低:
a)在CDB的逻辑块地址字段中指定的LBA之后的最后一个LBA,否则可能会遇到供应商特定的数据传输延迟;or
b)直接访问块设备上最后一个逻辑块的LBA。

返回的逻辑块地址应该大于或等于CDB中逻辑块地址字段指定的值。

BLOCK LENGTH IN BYTES field

BLOCK LENGTH IN BYTES字段包含由RETURNED logical BLOCKADDRESS字段表示的逻辑块中用户数据的字节数。此值不包括介质上记录的保护信息或附加信息(例如,ECC字节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 C++ 代码示例,用于在 Windows 环境下使用 SCSI READ 命令取 512K 数据: ```c++ #include <windows.h> #include <winioctl.h> #define SECTOR_SIZE 512 #define BUFFER_SIZE (SECTOR_SIZE * 1024) int main() { HANDLE hDevice = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice == INVALID_HANDLE_VALUE) { printf("Failed to open device, error code: %d\n", GetLastError()); return 1; } BYTE buffer[BUFFER_SIZE] = { 0 }; DWORD bytesReturned = 0; STORAGE_PROPERTY_QUERY storagePropertyQuery = { 0 }; STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader = { 0 }; storagePropertyQuery.PropertyId = StorageAdapterProperty; storagePropertyQuery.QueryType = PropertyStandardQuery; if (!DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery, sizeof(storagePropertyQuery), &storageDescriptorHeader, sizeof(storageDescriptorHeader), &bytesReturned, NULL)) { printf("Failed to retrieve adapter property, error code: %d\n", GetLastError()); CloseHandle(hDevice); return 1; } STORAGE_READ_CAPACITY readCapacity = { 0 }; if (!DeviceIoControl(hDevice, IOCTL_STORAGE_READ_CAPACITY, NULL, 0, &readCapacity, sizeof(readCapacity), &bytesReturned, NULL)) { printf("Failed to retrieve read capacity, error code: %d\n", GetLastError()); CloseHandle(hDevice); return 1; } DWORD sectorCount = readCapacity.DiskLength.QuadPart / SECTOR_SIZE; DWORD startingSector = 0; if (!DeviceIoControl(hDevice, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, NULL, 0, &bytesReturned, NULL)) { printf("Failed to verify device, error code: %d\n", GetLastError()); CloseHandle(hDevice); return 1; } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb = { 0 }; sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); sptdwb.sptd.PathId = 0; sptdwb.sptd.TargetId = 0; sptdwb.sptd.Lun = 0; sptdwb.sptd.TimeOutValue = 2; sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_IN; sptdwb.sptd.DataTransferLength = BUFFER_SIZE; sptdwb.sptd.DataBuffer = buffer; sptdwb.sptd.SenseInfoLength = SPT_SENSE_LENGTH; sptdwb.sptd.CdbLength = 10; sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, SenseBuf); sptdwb.sptd.Cdb[0] = 0x28; // SCSI READ command sptdwb.sptd.Cdb[1] = 0; sptdwb.sptd.Cdb[2] = (startingSector >> 24) & 0xFF; sptdwb.sptd.Cdb[3] = (startingSector >> 16) & 0xFF; sptdwb.sptd.Cdb[4] = (startingSector >> 8) & 0xFF; sptdwb.sptd.Cdb[5] = startingSector & 0xFF; sptdwb.sptd.Cdb[6] = 0; sptdwb.sptd.Cdb[7] = (BUFFER_SIZE / SECTOR_SIZE) & 0xFF; sptdwb.sptd.Cdb[8] = 0; sptdwb.sptd.Cdb[9] = 0; if (!DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), &sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), &bytesReturned, NULL)) { printf("Failed to execute SCSI READ command, error code: %d\n", GetLastError()); CloseHandle(hDevice); return 1; } CloseHandle(hDevice); return 0; } ``` 请注意,这只是一个简单的示例代码,可能需要根据实际情况进行更改。同时,使用 SCSI 命令需要具有足够的权限,并且必须小心谨慎,以免意外损坏设备。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值