1. 前言
本专题我们开始学习SCSI子系统的相关内容。本专题主要参考了《存储技术原理分析》、ULA、ULK的相关内容。本专题主要以硬件UFS为例,记录SCSI子系统的框架流程。
在系统启动过程中,扫描到SCSI主机适配器后,操作系统开始加载SCSI主机适配器驱动,即底层驱动。SCSI主机适配器驱动根据SCSI主机适配器模板分配SCSI主机适配器描述符,并添加到系统。在此之后需要通过SCSI主机适配器启动SCSI总线的扫描。
以UFS为例,UFS控制器不仅作为SCSI总线设备,同时也作为platform总线设备,它是通过ufshcd_pltfrm_init来执行Scsi_Host分配与添加,同时对于SCSI设备(即UFS device)的扫描是在ufshcd_async_scan完成。
对于ufs,执行路径为:
ufs_qcom_probe->ufshcd_pltfrm_init->ufshcd_init->async_schedule(ufshcd_async_scan, hba)->ufshcd_probe_hba->scsi_scan_host
kernel版本:5.10
平台:arm64
注:
为方便阅读,正文标题采用分级结构标识,每一级用一个"-“表示,如:两级为”|- -", 三级为”|- - -“
2.SCSI总线扫描方式
SCSI总线扫描的目的是通过协议特定或芯片特定的方式探测挂接在主机适配器后面的target和LUN,为他们在内存中构建相应的数据结构,将他们添加到系统中,不同的主机适配器可能实现不同的拓扑结构和设备添加机制,列举三种:

对于SPI协议,SCSI主机适配器驱动可以调用SCSI中间层提供的扫描算法完成SCSI总线设备的扫描,扫描过程描述如下:

注:
1.对于UFS设备来讲,SCSI低层驱动的queuecommand就是ufshcd_queuecommand
2.INQUIRY、REPORT_LUNS命令是SCSI命令,由它构建CDB,组成了UFS的UTP层UPIU的Transfer specific fields
SCSI中间层提供扫描SCSI总线的服务函数是scsi_scan_host,它一般在适配器平台驱动的probe中执行,它采用的就是上面描述的向各个<channel, id, lun>发送INQUIRY的命令方式

3.scsi_scan_host
void scsi_scan_host(struct Scsi_Host *shost)
|--data = scsi_prep_async_scan(shost);
| if (!data)
| do_scsi_scan_host(shost);
| scsi_autopm_put_host(shost);
| return;
|--async_schedule(do_scan_async, data);
|--do_scan_async(void *_data, async_cookie_t c)
|--struct async_scan_data *data = _data;
|--struct Scsi_Host *shost = data->shost;
|--do_scsi_scan_host(shost);
|--scsi_finish_async_scan(data);
对于ufs,执行路径为:
ufs_qcom_probe->ufshcd_pltfr

本文详细介绍了SCSI子系统的工作流程,特别是在系统启动时如何扫描和添加UFS设备。首先,当SCSI主机适配器被发现后,操作系统加载其驱动并初始化。接着,通过`scsi_scan_host`函数启动SCSI总线扫描,该过程包括向每个target和LUN发送INQUIRY命令以探测设备。对于UFS设备,扫描路径涉及`ufs_qcom_probe`等一系列函数调用。在scsi_scan_host中,`scsi_prep_async_scan`和`async_schedule`用于异步扫描,进一步调用`scsi_probe_and_add_lun`探测并添加逻辑单元到系统。整个过程涉及到设备描述符的分配、命令的发送以及设备的注册等步骤。
最低0.47元/天 解锁文章
1860

被折叠的 条评论
为什么被折叠?



