SCSI子系统基础学习笔记 (之UFS子系统) – 1.2 概述(软件部分)

1. 前言

本专题我们开始学习SCSI子系统的相关内容。本专题主要参考了《存储技术原理分析》、ULA、ULK的相关内容。本专题主要以硬件UFS,控制器以高通UFS控制器为例,记录SCSI子系统的框架流程。本文是UFS子系统软件概述部分。

kernel版本:5.10
平台:arm64

注:
为方便阅读,正文标题采用分级结构标识,每一级用一个”-“表示,如:两级为”|- -“, 三级为”|- – -“

2. UFS子系统软件架构

在这里插入图片描述
如上图所示,以UFS为例,UFS子系统实际就是SCSI子系统的低层,也就是UFS控制器的驱动。

  • UFS平台驱动
    主要获取跟平台相关的一些属性,如对于高通来讲,就会获取高通平台DTS中定义的UFS相关属性。此处的UFS平台驱动特指ufshcd-pltfrm。作为一个platform device,它的驱动在注册时触发了ufshcd_pltfrm_probe的执行,ufshcd_pltfrm_probe进而调用了ufshcd公共层的接口主要是ufshcd_alloc_host和ufshcd_init。同时通过of_find_device_by_node(ufs_variant_node)直接获取到最底层ufs host驱动也就是ufshcd-qcom的platform device,它里面保存了对ufs host的操作函数集,并传递给UFS公共层,这样UFS公共层就可以实现对底层ufs host的寄存器操作。

  • UFS公共层
    主要提供了ufs公共的一些行为,策略以及各种命令处理,错误恢复等的接口,其中ufshcd_alloc_host实现了scsi_host的分配,ufshcd_init实现对scsi控制器的初始化。ufshcd公用层将从UFS平台驱动拿到底层ufshcd-qcom的操作函数集实现对底层ufs控制器的操作。
    注:struct scsi_host_template类型变量ufshcd_driver_template是在本层定义,struct scsi_host_template代表了一个scsi host的基础定义模板,任何一个scsi控制器都需要定义此数据结构,而此处的scsi控制器就是ufs控制器

  • UFS HOST物理层
    实际的scsi控制器驱动层,实现了对特定平台的scsi host的寄存器操作,此处就是高通平台的UFS控制器

3. UFS模块框图

在这里插入图片描述

4. UFS领域模型

在这里插入图片描述
上图是整个UFS驱动的核心框图,它主要由UTRD, UCD, UTMD以及一些data buffer构成。UFS host驱动通过分配和使用UTRD描述符和UTMRD描述符来与host控制器硬件通信。host控制器系统内存可以同时接受多达32个UTRD描述符和8个UTMRD描述符,他们分别组成了UTRD LIST和UTMRD LIST。每个UTRD描述符指向一个UCD区域,UCD包括了command UPIU区域、response UPIU区域以及PRDT区域。其中command UPIU区域和response UPIU区域将来用于存放组装的UPIU;而PRDT区域指向了一些sg segments,PRDT表中的每一项用于管理一个sg segment,即一段数据buffer,存储需要传输的数据或要接受的数据。UTRD LIST的地址和UTMRD LIST的地址分别告知UFS HOST CONTROLLER的UTP Transfer Request和UTP Task Management Request寄存器,这样UFS控制器可以自动发送和接收UPIU。
在这里插入图片描述

上图也体现出了ufs驱动的核心数据结构之间的关系,所有的utp_transfer_req_desc(UTRD)组成一个UTRD LIST,一共可达32个,list中的每一项用于管理一个utp_transfer_cmd_desc(UCD),UCD也有32个,utp_transfer_req_desc(UTRD)的command_desc_base_addr指向了一个utp_transfer_cmd_desc(UCD),command_desc_base_addr是一个DMA地址。
utp_transfer_cmd_desc(UCD)由command upiu, response upiu和prd_table构成,ufshcd_lrb的ucd_req_ptr/ucd_req_dma_addr、
ucd_rsp_ptr/ucd_rsp_dma_addr、ucd_prdt_ptr/ucd_prdt_dma_addr就分别指向了这些区域,ufshcd_lrb同样有32个,因此utp_transfer_req_desc(UTRD)、utp_transfer_cmd_desc(UCD)、ufshcd_lrb是一一对应的关系。

  • ufs_hba
    每个ufs控制器的私有数据,对于高通的UFS控制器,它的 priv成员变量一般指向了struct ufs_qcom_host

  • Scsi_Host
    代表scsi子系统层级的的host,它struct scsi_host_template *hostt与struct scsi_host_template关联,它是在ufshcd_alloc_host时分配得到的

  • struct scsi_host_template
    是scsi_host在下一层级子系统(如UFS)的代表,如对于ufs子系统实现为ufshcd_driver_template。ufshcd_driver_template为scsi子系统定义的scsi_host操作函数集模板,ufs host作为scsi_host也要实现这套模板,主要定义在ufshcd.c中

  • ufs_qcom_host:
    表示一个ufs控制器,它通过成员变量*hba与struct ufs_hba关联,它在ufs_qcom_init时被创建

  • utp_transfer_req_desc
    UTRD描述符,数目为32个。UTP传输请求描述符结构体(UTRD),包含了头、UCD UPIU物理地址(来源于struct utp_transfer_cmd_desc分配DMA带出的物理地址)、Response 长度和偏移、PRDT长度和偏移。

  • struct utp_task_req_desc
    UTP任务管理请求描述符结构体(UTMRD),数目为8个,包含了头、请求UPIU、响应UPIU

  • utp_transfer_cmd_desc
    UCD描述符,数目为32个。包含了command upiu和response upiu空间,以及一个维护多个内存segment的prd_table。UCD包含CMD UPIU缓冲区, RESPONSE UPIU缓冲区, PRD TABLE缓冲区,也即是说UCD描述的就是三个缓冲区,这里命令缓冲区除了存放command CDB,也可以存放query request,同样响应UPIU缓冲区除了可以存放command响应UPIU,也可以存放query request的响应UPIU;

  • ufshcd_sg_entry
    用于描述每个内存segment的起始地址和长度

  • request_desc_header
    为utp_transfer_req_desc(UTRD)和utp_task_req_desc(UTMRD)的头

  • ufshcd_lrb
    local reference block,数目与utp_transfer_req_desc(UTRD)和utp_transfer_cmd_desc(UCD)的一致,它为执牛耳者,将命令描述符结构体UCD的command_upiu,response_upiu,prd_table的地址保存到自己的结构体中。ufshcd_lrb,utp_transfer_req_desc与utp_transfer_cmd_desc是一一对应的,ufshcd_lrb的ucd_req_ptr/ucd_req_dma_addr, ucd_rsp_ptr/ucd_rsp_dma_addr,, ucd_prdt_ptr/ucd_prdt_dma_addr分别保存了utp_transfer_cmd_desc的command_upiu地址,response_upiu地址,prd_table地址。


  • utp_upiu_cmd
    代表cmd upiu结构体,主要包含了 数据传输长度,CDB(command descriptor block),此结构体没有包含header,由utp_upiu_req将utp_upiu_header和utp_upiu_cmd进行组装

  • utp_cmd_rsp
    代表response upiu结构体,它与utp_upiu_cmd相对应
    注:utp_upiu_cmd和utp_cmd_rsp对应APP layer的UCS

  • utp_upiu_query
    代表query request upiu和query response upiu结构体,此结构体没有包含header,由utp_upiu_req将utp_upiu_header和utp_upiu_query进行组装
    注:utp_upiu_query对应APP layer的device manager

  • utp_upiu_req
    通用的UPIU REQUEST结构体,它代表了COMMAND UPIU或QUERY REQUEST UPIU,某一时刻只能用作一种。它是在封装UPIU之前的数据,如果是一个COMMAND UPIU,则会封装为一个CDB

  • utp_upiu_rsp
    通用的UPIU RESPONSE结构体,它代表了COMMAND RESPONSE UPIU或QUERY RESPONSE UPIU,某一时刻只能用作一种

  • utp_upiu_task_req
    代表task request upiu结构体

  • utp_upiu_task_rsp
    代表task response upiu结构体
    注:utp_upiu_task_req和utp_upiu_task_rsp对应APP layer的task manager

  • utp_upiu_header
    upiu的头

  • ufs_query_req
    代表查询请求query request,即QUERY REQUEST UPIU

  • ufs_query_res
    代表查询响应query response, 即QUERY RESPONSE UPIU
    注:ufs_query_req和ufs_query_res对应APP layer的device manager

参考文档

存储技术原理分析


版权声明:本文为jasonactions原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。