1 概述
UAS(USB Attached SCSI)是一种位于SCSI协议框架下传输层的一种协议,其作用是通过基于USB的应用层协议约定,将SCSI的协议数据(Protocol Data Unit)用USB进行封装,从而实现使用USB物理连接进行SCSI协议通信的方式。
UAS实际上定义了两个规范,第一个是规定UAS本身使用方式的USB Attached SCSI,另一个是定义了UAS设备类型的Universal Serial Bus Mass Storage Class - USB Attached SCSI Protocol (UASP)。
目前网上介绍UAS相关概念的比较少,如何具体使用UAS和协议细节的就更少了,本文希望能够基于多个SCSI规范协议,并且与BOT进行对比,来帮助开发者更快理解UAS协议及如何使用。
由于UAS是建立在USB和SCSI的基础之上的,而USB和SCSI这两个本身又是非常庞大复杂的协议,为了便于阅读,接下来会先简单介绍一下UAS会涉及到的USB和SCSI的一些相关内容。
2 USB及SCSI基础
2.1 USB应用层简介
在USB 领域内,传输的发起方叫做Host(主机),接收方叫做Device(设备)。而在SCSI领域当中,传输的发起方叫做Initiator(发起方,启动器),接收方叫做Target(目标器)。在不同领域内虽然名字不一样,但是代表的含义都是相近的,为了便于描述,本文后面都将传输的发起方都称为主机,接收方都称为设备。
USB3的数据传输是通过数据包(DP,Data Packet)来进行传输的,当主机或是设备成功接收DP之后,都应当回复一个ACK(Acknowledgement)信号,表示DP成功接收到了。
之所以介绍ACK,是因为ACK在UAS当中被用作SCSI命令传输阶段的标志,在下文会用到。
USB传输定义了4种传输类型:控制传输,中断传输,批量传输和同步传输,UAS只会用到其中的控制传输(Control Transfer)和批量传输(Bulk Transfer)。其中控制传输通常只在USB刚建立好通信后获取描述符(Descriptor)阶段会用到,目的是获取一些设备最基本的运行状态,包括使用的是BOT还是UAS。批量传输则是用于进行大量的数据包传输,数据包的内容包含了SCSI的PDU等等。
最后还需要介绍一点的就是USB的端口(End Point),关于这个端口可以理解为当进行USB传输时,数据最开始需要一个FIFO来进行缓存,这样一个缓存区就被定义为一个端口。如果所有的DP都使用同一个端口的话,那么不管是什么类型的数据,都需要等上一个数据包处理完成之后才能进行本次传输。但是如果将数据类型进行区分,比如区分出来命令数据包、逻辑数据包等等,让不同的数据走不同端口的话,可以一定程度的提高性能。
1.2 SCSI协议结构框架和SCSI命令集
小型计算机系统接口(SCSI,Small Computer System Interface)是一种用于计算机及其周边设备之间(硬盘、软驱、光驱、打印机、扫描仪等)系统级接口的独立处理器标准。虽然名字里面带个接口,但实际上是一种应用层协议。简单理解,就是系统想要跟任何硬件进行数据交互的话,都是通过SCSI协议来进行的,通过这样的分层,在应用层的系统不需要去适配各种各样的通信总线协议。
SCSI由于其海纳百川的拓展性和兼容性,其协议结构非常的庞大,下图展示了一部分SCSI协议的内容:
最上一层代表的是系统的各种应用驱动规范,中间介绍了SCSI命令集类型和SCSI架构,再往下就是SCSI所适配的部分传输总线。
如此庞大的协议很显然无法在一个文章里面说明,在这里只简单介绍一下SCSI最基本的东西:一条完整的命令传输过程和UAS所使用的指令集。
1.1.2.1 一个完整的SCSI命令组成
在SCSI Architecture Model(SAM)文档当中,定义了一次完整的SCSI命令收发该如何完成。任何传输协议都应当想办法适配这样一套规定。
完整的SCSI传输包含以下几个阶段:
- 命令发送请求(Send SCSI Command request)
- 命令接收标志(SCSI Command Received indication)
- 命令发送完成响应(Send Command Complete response)
- 命令完成确认(Command Complete Received confirmation)
在这里面所描述的命令,指的是SCSI的命令,也就是CDB(Command Descriptor Block),在CDB的结构当中,规定了不管什么类型第一个Byte必须表示的为Operation code(OpCode),不同的OpCode即代表了不同的命令,不同的指令集就表示是由不同的OpCode组成。
一次完整的命令传输除了命令,SCSI还规定设备必须回复命令状态(Status Code),命令状态包括了命令正常完成等各种状态,在后面的章节中会在详细介绍。
1.1.2.2 UAS所使用的SCSI命令集
UAS所需要支持的SCSI指令主要来来源于SPC(SCSI Primary Commands)和SBC(SCSI Block Commands),但是如果想要从包括UAS Spec在内的这三份文档当中去找到需要支持的命令集那可太难了。所幸的是还有一份UAS合规性验证标准UASP-ComplianceTestSpec,里面非常明确的列出了UAS要支持的命令及其来源:
(就这份资料整理,高低值得一个赞…)
3. UAS协议说明
在介绍完相关的一些基础知识之后,可以开始进行UAS的协议说明了,接下来大部分内容从USB Attached SCSI - 2当中总结得到的,有疑问的话也可以对照这一份Spec来看。
3.1 如何上报传输协议为UAS
在USB建立好连接后,会进行1.1.1章节当中所描述过的USB控制传输,通常被成为USB枚举,在这期间设备可以给主机上报各类描述符(Descriptor)。USB在进行UAS类型的描述符上报时,至少需要包含以下4种类型的描述符:
- 设备描述符(Device Descriptor)
- 配置描述符(Configuration Descriptor)
- 接口描述符(Interface Descriptor)
- 4个端口描述符(Endpoint Descriptors)
3.1.1 设备描述符:
以下几个字段,必须按照上图所示来进行配置:
- LENGTH
- DESCRIPTOR TYPE
- DEVICE CLASS
- DEVICE SUBCLASS
- DEVICE PROTOCOL
其余字段根据USB-2和USB-3协议上所规定的配置来进行配置即可,比如MAX PACKET SIZE,USB-3当中即可配置为512也可以配置为1024。
关于DEVICE CLASS,DEVICE SUBCLASS和DEVICE PROTOCOL的说明,在USB3和USB2的协议文档当中会有详细的介绍。另外在这里还上报了比较重要的ID VENDOR和ID PRODUCT,也就是常说的VID,PID。
3.1.2 配置描述符
该描述符,UAS规范只约束了长度和类型,其他参数都要参考USB3和USB2的协议。比较容易费解的是NUM INTERFACES,指的是可以配置的接口数量,这个指的不是端口数量,而是后面要说明的接口描述符的数量。如果该值配置为多个的话,那么要发送多个接口描述符。
3.1.3 接口描述符
以下字段必须按照上图所示配置:
- LENGTH
- DESCRIPTOR TYPE
- INTERFACE CLASS
- INTERFACE SUBCLASS
- INTERFACE PROTOCOL
这里面包含了用于区分BOT和UASP的字段,就是InterfaceProtocol,如果该字段值为50h的话,表示当前协议为BOT,如果该字段值为62h的话,则表示UAS。这个类型的定义在USB Mass Storage Class Specification Overview当中:
还有另外一个非常重要的潜规则字段,就是NUM ENDPOINTS端口数量。虽然没有着重说明,但是UAS最少需要支持的端口数量为4,下图为BOT协议当中描述的Interface Descriptor,其中就说明了NumEndpoints最少为2:
UAS之所以端口数量最少为4,是因为UAS将不同的DP分类为4个类型的数据:Data-in,Data-out,Command和Status。而BOT当中,只将数据分类为Bulk-in和Bulk-out。
3.1.4 端口描述符
端口描述符包含四类,其中大部分字段都已经明确规定,只有端口号可以自行定义:
该描述符应当为每一个端口描述符之后的第一个描述符字段,代表给这个端口分配了一个使用类型。
在UAS当中,尽管定义了四种端口类型,但是端口描述符还是只分成了Bulk-in和Bulk-out两类,具体的使用是由Pipe Usage Descriptor来定义的。
说明一下Pipe(管道)表示的是一种抽象的逻辑概念,代表设备和主机之间的数据传输关系。
定义端口类型的PIPE ID如下所示:
3.2 传输控制
UAS传输是通过Information Units来进行控制的,不同的IU类型识别是通过IU ID来进行区分的。
IU ID总是位于Command 和Status 管道传输的数据当中的第一个Byte,IU ID所对应的类型如下:
下面介绍一下UAS所包含的所有类型的IU及其作用。
3.2.1 Command IU
该类型IU承担了SCSI命令传输的功能,上图当中的CDB字段,即为SCSI当中的Command Descriptor Block字段(详见SPC-4)。
在UAS所有类型的IU当中,都包含了一个用于关联Command和Status的TAG,主机通过TAG来确认设备回复的Status是面向哪一个Command。如果在并发的命令当中出现了同样的TAG,那么设备应当终止命令响应。
除此之外,COMMAND IU还包含了命令优先级,命令属性:
其中ACA表示的是一种自动应急处理,建立ACA之后主机只会接收指定命令的响应,现在比较少使用。
由于CDB本身是可变长度的,因此还有字段描述了CDB的附加长度,如果本身是短CDB,那么多余的数据应当被忽略。LOGICAL UNIT NUMBER标记了当前命令是发送给哪一个LOGIC UNIT。
3.2.2 READ/WRITE READY IU
由设备发送到主机,表示准备好进行数据接收/发送。
但是如果是通过USB3进行的连接,设备就不应当回复Read/Write Ready IU,而是回复一个USB3当中定义的ERDY(Endpoint Ready),ERDY虽然不是IU,但是也包含可以用于回复TAG的字段。
3.2.3 SENSE IU
SENSE IU是设备发送给主机的,用于传递SCSI状态,SENSE IU的传递被包含在了完整SCSI命令传输的定义当中,也就是命令发送完成响应(Send Command Complete response)阶段。
。
需要说明的是STATUS QUALIFIER虽然定义了字段在那里,但是目前为止还没有实际用途。
STATUS字段代表的就是在1.1.2.1当中所描述,完整SCSI传输当中需要包含的Status codes,可以在SAM文档当中查询,列表如下:
而后面的SENSE DATA,只有当Status codes为CHECK CONDITION时才会包含在内,通常是在命令出现异常需要进行状态检查时,或者在收到REQUSET SENSE命令的时候才会出现SENSE DATA,SENSE DATA的具体定义详见SAM-4 5.8.6章节。
3.2.4 RESPONSE IU
用来从设备传递任务管理状态给主机,与SENSE IU不一样的是,RESPONSE IU是用来回应TASK MANAGEMENT IU的,或者是当COMMAND IU出现错误的时候来报告错误信息的。
3.2.5 TASK MANAGEMENT IU
TASK MANAGEMENT IU是由UAS主机的任务管理器发送的,用于进行指定逻辑单元的任务管理。
根据TASK MANAGEMENT FUNCTION字段,可以进行终止指定命令或者终止全部命令等操作。
4. UAS与BOT的差异
BOT比UAS早诞生了大约9年,UAS是和USB3.0一同出现的。UAS作为新出现的传输协议,与BOT相比有很多的优点,接下来将会逐一介绍UAS和BOT之间的一些差异。
4.1 性能
由于UAS的命令流处理优化,一条命令的处理完成不需要等待上一条命令处理,即使在BOT和UAS使用同样USB3带宽的情况下,UAS的性能依旧比BOT高出不少。之所以有这样的明显差距,主要得益于UAS提高了对CPU的性能利用率。
4.2 全双工
USB本身是支持全双工数据传输的,但是BOT协议并没有支持全双工模式的命令,在UAS当中新增了对全双工传输命令XDWRITEREAD(10) (详见SBC-3)的支持,可以实现同时data-out和data-in的数据传输:
4.3 命令平行处理
在BOT当中,一条SCSI在处理完成之前不允许发送新的命令,但是在UAS当中允许进行命令的并行,也就是一条命令完成之前可以发送新的命令,并且一条命令的完成状态可以在另一条命令正在传输的过程当中进行,能实现这样的功能主要得益于UAS对全双工的支持和多端口的设计。
4.4 命令集
UAS所支持的SCSI命令在BOT的基础上进行了一些扩展,如FORMAT UNIT、SEND DIAGNOSTIC和全双工命令XDWRITEREAD(10)等等。
并且基于TASK MANAGEMET IU的,还额外支持了针对UAS的任务管理命令,如下表所示:
另外需要说明的是,尽管UAS可以支持SCSI的Unmap命令(类似SATA的Trim),但是这个并不是必须的,可以选择不支持。在SBC-3当中定义了Thin provisioning,是一类可以提供数据精简的操作,如果设备支持这类操作的话,在READ CAPACITY(16)(Opcode为9Eh)命令返回的数据当中,TPE(thin provisioning enabled)字段需要为1。
所以逻辑上并不是UAS设备支持Unmap,而是BOT的主机和设备都没有支持Unmap,UAS的主机选择支持Unmap,所以UAS设备才可以选择支持Unmap操作。是否支持Unmap主要受限的还是SCSI协议,而不是UAS协议。
Unmap操作对于固态存储的设备来讲有非常大的好处,可以减少逻辑数据分区当中的有效数据,从而提高回收效率降低磨损,因此Unmap也被认为是UAS的一大亮点。
参考文档
Universal Serial Bus 3.2 Specification(USB3.2)
Universal Serial Bus Mass Storage Class Specification Overview
USB Attached SCSI - 2
UASP-ComplianceTestSpec
Universal Serial Bus Mass Storage Class Compliance Test Specification
SCSI Architecture Model - 4(SAM - 4)
SCSI Primary Commands - 4(SPC - 4)
SCSI Block Commands - 3 (SBC-3)
Universal Serial Bus Mass Storage Class Bulk-Only Transport(BOT)