系统产品前端接口


目录:

1. SATA

2. UFS over unipro


Linux Scsi子系统框架介绍 - 内核工匠 - 博客园 (cnblogs.com)


linux内部的任何大的驱动子系统(例如mmc,scsi,pcie,usb等等)都是以硬件对象为基础设计的,包括

    • 硬件各级设备的睡眠和唤醒顺序,决定了软件上的设备父子关系。例如sd,emmc先sleep,sdio才能sleep。

    • 硬件上的连接关系决定了软件上扫描顺序。例如pcie现有rc虚拟bridge,再扫描一级总线上的各种外设,扫到了bridge才能再递归扫描下一级总线上的外设。

    • 硬件总线上传输的信息的封装方式,决定了多级设备的驱动,各自处理的范围。例如ufs驱动负责upiu等等处理,scsi子系统负责scsi命令的处理。


Scsi只是一个协议,因此各种五花八门的控制器都可以使用scsi进行交互。因此这个“通道”是借助各种控制器的驱动来完成的。有点像协议分层,scsi类似于协议层,而物理层,链路层则交给了各种控制器去完成。在软件上,linux scsi子系统发送和接收的任何scsi命令都是由底层物理设备对应的驱动程序完成的,例如可以通过usb某个子设备驱动或者通过ufs驱动去实现scsi命令传输

每个SCSI device内部可以看成被分为被多个target,每个target下面接着多个lun;lun是能够接收scsi命令的主体。例如可以是一个物理硬盘,一个光驱;对ufs而言是ufs固件虚拟出来的rpmb,boot0,boot1;也有一些lun不是物>理实体但是能接收scsi命令,也被看作为lun,例如report luns可以响应scsi report luns command返回设备lun总数等信息。因此软件上每个lun在linux的通用块设备层都有独享的一个request queue。(注意下,有时候一个硬盘>通过GPT或者MBR分为多个逻辑分区;它们是一个lun里面,共用一个request queue。关于逻辑分区,不在linux scsi子系统中处理)



SCSI命令分类及作用描述

2.1 查询类

INQUIRY

inquiry命令用于查询device的一些关键信息,例如设备制造商,产品名称,FW版本号等,通常host上电启动时会下发inquiry命令获取设备信息,针对不同厂商的器件可能会使用不同的配置项。

REPORT LUNS

report luns命令用于像host上报当前device中使能的normal lun的lun ID,以及device中支持的well know lun 的lun ID。

READ CAPACITY

读取指定逻辑单元的容量和部分配置信息。

REQUEST SENSE

request sense命令用于查询指定的lun是否存在sense data,如果有的话会通过data in UPIU返回给主机。同时request sense命令可以清除device复位产生的UAC标记,并且命令不会报失败(可能这才是host发request sense的主要目的)。

TEST UNIT READY

test unit ready命令主要用于测试指定逻辑单元是否能够响应命令,但是实际使用场景不多。

SEND DIAGNOSTIC

host下发send diagnostic命令让device执行指定的自检操作。但是host并不能判断device是否真的正确的执行了自检,换句话说host无法感知自检结果,所以对于device而言此功能可有可无。

2.2 读写类

PRE-FETCH

主机下发pre-fetch命令,让device将指定LBA的数据取出放在指定的buffer中。从命令的字面意思上看,host想在让device执行预取的操作,提升后续读命令的性能。但是host同样无法感知device是否真的执行的pre-fetch>命令。这是因为在不考虑性能的情况下,先下发预取再下发读命令 和 直接下发读命令对于host的结果是完全相同的。同时由于UFS设备资源有限,可能并没有专用的buffer用于预取命令(空闲时device GC等后台操作仍旧会占用buffer)。

READ

read命令包含read(6)/read(10)/read(16),不同的read命令LBA的寻址范围存在区别。主机下发读命令读取指定LBA的数据,device FW会通过FTL映射表获得指定LBA对应的物理地址,然后读取相应数据返回给主机。

WRITE

write命令包含write(6)/write(10)/write(16),不同的write命令LBA的寻址范围存在区别。主机下发写命令修改指定LBA的数据,device将数据写入到flash之后需要修改FTL映射表(flash无法在有数据的地址上覆盖写)。

UNMAP

主机下发unmap命令要求device清除某个LUN中指定LBA的数据,实际上只会修改映射表。根据LU中bProvisionType的不同,unmap命令被分为erase和discard两种操作。其中erase要求host读取经过unmap的LBA时返回全0,而discard则返回随机值。

FORMAT UNIT

格式化指定逻辑单元,如果指定了device well know lun,则将格式化全盘。实现上与UNMAP命令相似。

SYNCHRONIZE CACHE

将device中指定LBA的数据下刷到flash中,也可以将buffer中所有数据一起下刷,因为host无法预期哪些数据会缓存在device buffer中。

VERIFY

下发verify命令校验指定LBA中的数据能否被正常读出。

SECURITY PROTOCOL OUT

用与下发加密类的操作。例如读取/写入 RPMB LUN的数据,或者配置各个逻辑单元的安全写保护。

SECURITY PROTOCOL IN

用于获取SECURITY PROTOCOL OUT命令携带指令的执行结果,与SECURITY PROTOCOL OUT组成一个完整的命令序列。写入类操作需要2个SECURITY PROTOCOL OUT 加 1个SECURITY PROTOCOL IN。读取类操作需要1个SECURITY PROTOCOL OUT和1个SECURITY PROTOCOL IN。

2.3 管理类

START STOP UNIT

用于调整device的电源状态以及指定LU的启动与关闭。在调整device电源状态的场景中,start stop unit命令与硬件平台息息相关,不同的UFS设备硬件资源不同,需要执行的操作也并不相同。可以通过query配置上电启动>时的电源状态。

MODE SENSE

用于查询mode pages当前值/保存值/默认值/可变值,UFS协议中支持control,caching以及read write error recovery。

MODE SELECT

与mode sense配合使用,用于修改mode pages的当前值或者保存值。可以用于配置指定LU的软件写保护。

2.4 杂项

READ BUFFER

读取指定buffer中的数据,可以用与读取device侧的err history信息。

WRITE BUFFER

向指定buffer中写入数据,可以用于FFU升级device FW。

另外read buffer与write buffer通常更多的用于实现VCMD。


来自 <https://www.cnblogs.com/fengdan8778/p/15957488.html>