SCSI子系统基础学习笔记 - 3. SCSI设备探测

本文详细介绍了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`探测并添加逻辑单元到系统。整个过程涉及到设备描述符的分配、命令的发送以及设备的注册等步骤。

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

`rescan-scsi-bus.sh` 是一个用于在 Linux 系统中扫描 SCSI 总线、识别新添加或移除的 SCSI 设备(如硬盘、磁带机等)的脚本工具。它通常位于 `/usr/bin/rescan-scsi-bus.sh`,在虚拟化、存储扩容、热插拔等场景中非常常用。 --- ### 📌 `rescan-scsi-bus.sh` 和 `rescan-scsi-bus.sh -a` 的区别如下: | 命令 | 说明 | 行为 | |------|------|------| | `rescan-scsi-bus.sh` | 扫描整个 SCSI 总线,检测新增设备并通知内核 | 只会 **添加** 新设备,不会移除已断开的设备 | | `rescan-scsi-bus.sh -a` | 添加 `-a` 参数(即 `--add`) | 同上,只是明确表示添加新设备(等同于不带参数) | | `rescan-scsi-bus.sh -r` | 添加 `-r` 参数(即 `--remove`) | 会 **先移除所有未连接的设备**,再扫描新增设备 | --- ### ✅ 常见用法示例: 1. **只扫描新增设备(默认行为):** ```bash rescan-scsi-bus.sh ``` 2. **明确指定添加设备(与上面等效):** ```bash rescan-scsi-bus.sh -a ``` 3. **先清理断开设备,再扫描新增设备:** ```bash rescan-scsi-bus.sh -r ``` --- ### 🔍 适用场景: - **新增磁盘或 LUN**:使用 `rescan-scsi-bus.sh` 或 `-a` 参数即可。 - **移除旧的无效设备信息**:使用 `-r` 参数。 - **虚拟化/云平台热插拔磁盘后**:建议使用 `-r` 来确保干净扫描。 --- ### 📝 小提示: - 如果你使用的是 **RHEL/CentOS 7+ 或 Ubuntu 18.04+**,也可以使用 `echo "- - -" > /sys/class/scsi_host/hostX/scan` 手动扫描。 - 该脚本依赖于 `sg3_utils` 包,请确保已安装。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值