当前位置: 首页 > news >正文

SCSI驱动与 UFS 驱动交互概况

SCSI子系统概况

SCSI(Small Computer System Interface)子系统是 Linux 中的一个模块化框架,用于提供与存储设备的通用接口。通过 SCSI 子系统,可以支持不同类型的存储协议(如 UFS、SATA、SAS),使操作系统能够通过相同的命令集与这些设备交互。

驱动的分工

  • UFS 驱动:负责与 UFS 主控直接交互,包括初始化、配置和电源管理。UFS 驱动会解析设备树(DTS)中的信息,启动并配置硬件,使其进入工作状态。
  • SCSI 子系统:提供一个上层的抽象层,将对存储设备的访问抽象为标准 SCSI 命令(如读、写、格式化)。应用程序和文件系统通过 SCSI 子系统向存储设备发出 I/O 请求,而 SCSI 子系统负责将请求传递给对应的驱动。

初始化阶段

UFS 驱动注册到SCSI系统

  • UFS驱动会等待调用,调用的话他就是接收或者发送通用SCSI的命令,处理这些操作就需要一个主机,所以首先scsi_host_alloc 会分配一个主机适配器scsi host。 代码在**/** drivers / scsi / hosts.c
  • scsi_add_host 注册主机适配器,使得SCSI 子系统得知有一个新的 SCSI 主机适配器(即 UFS 设备)已经上线并准备接受命令。

设备扫描和初始化

  • 代码在drivers / scsi / scsi_scan.c
  • 一旦确认设备在线,SCSI 子系统会为每个检测到的 UFS 存储设备分配一个 struct scsi_device 结构体。这一结构体包含设备的基本信息和状态,使系统可以通过这个结构体与 UFS 设备进行读写操作。
  • 发现到 UFS 设备后,SCSI 子系统会为其分配 SCSI 设备结构(struct scsi_device),并准备好用于与操作系统和文件系统交互,抽象成操作系统或文件系统能够交互的设备。
void scsi_scan_host(struct Scsi_Host *shost)
{struct async_scan_data *data;if (strncmp(scsi_scan_type, "none", 4) == 0 ||strncmp(scsi_scan_type, "manual", 6) == 0)return;if (scsi_autopm_get_host(shost) < 0)return;data = scsi_prep_async_scan(shost);if (!data) {do_scsi_scan_host(shost);scsi_autopm_put_host(shost);return;}/* register with the async subsystem so wait_for_device_probe()* will flush this work*/async_schedule(do_scan_async, data);/* scsi_autopm_put_host(shost) is called in scsi_finish_async_scan() */
}
EXPORT_SYMBOL(scsi_scan_host);

文件IO的处理流程

系统发起读写请求时,SCSI子系统和UFS 驱动协同合作,将请求传递到UFS 设备。

  • 请求创建:系统通过读写命令的系统调用来调用虚拟文件系统,虚拟文件进一步调用具体的文件系统例如F2FS, F2FS的读写操作进一步传达到SCSI 子系统,SCSI最终调用 UFS子系统,所以请求在SCSI这块生成SCSI命令描述块。
    请求处理:SCSI 子系统封装命令描述块为SCSI命令,并调用ufshcd_queuecommand函数
static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
{// 获取 UFS 主控(Host Bus Adapter, HBA)的私有数据struct ufs_hba *hba = shost_priv(host);// 从 SCSI 命令提取请求的 tag,用于定位 UFS 请求块(LUN/队列标识)int tag = scsi_cmd_to_rq(cmd)->tag;struct ufshcd_lrb *lrbp;int err = 0;struct ufs_hw_queue *hwq = NULL;// 检查 UFS 主控当前的状态switch (hba->ufshcd_state) {case UFSHCD_STATE_OPERATIONAL:// 如果 UFS 处于正常操作状态,则继续处理命令break;case UFSHCD_STATE_EH_SCHEDULED_NON_FATAL:/** SCSI 错误处理程序可能在 UFS 错误处理中调用此命令队列函数。* 当错误处理中状态从 RESET 转到 EH_SCHEDULED_NON_FATAL 时,防止* 在此情况下发出新的请求。*/if (ufshcd_eh_in_progress(hba)) {err = SCSI_MLQUEUE_HOST_BUSY; // 主机忙碌,暂时无法处理命令goto out;}break;case UFSHCD_STATE_EH_SCHEDULED_FATAL:/** 在错误处理准备阶段会调用 pm_runtime_get_sync()。* 若从 HBA 的电源管理操作发送 SCSI 命令(如 SSU 命令),* 如果 UFS 状态不佳而允许命令通过,可能导致超时阻塞。* 因此直接返回错误,以便错误处理程序恢复 PM 错误。*/if (hba->pm_op_in_progress) {hba->force_reset = true;set_host_byte(cmd, DID_BAD_TARGET); // 设置命令目标状态为 BADscsi_done(cmd); // 完成命令goto out;}fallthrough; // 继续往下执行到 RESETcase UFSHCD_STATE_RESET:err = SCSI_MLQUEUE_HOST_BUSY; // 主机忙碌goto out;case UFSHCD_STATE_ERROR:set_host_byte(cmd, DID_ERROR); // 设置错误状态scsi_done(cmd); // 结束命令goto out;}// 重置请求的中止计数hba->req_abort_count = 0;// 保持 UFS 资源ufshcd_hold(hba);// 初始化逻辑请求块(Logical Request Block, LRB)信息lrbp = &hba->lrb[tag];lrbp->cmd = cmd; // 设置 SCSI 命令lrbp->task_tag = tag; // 任务标识lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); // 逻辑单元号转换lrbp->intr_cmd = !ufshcd_is_intr_aggr_allowed(hba); // 检查是否允许中断聚合// 准备加密信息ufshcd_prepare_lrbp_crypto(scsi_cmd_to_rq(cmd), lrbp);// 标记该请求不跳过中止lrbp->req_abort_skip = false;// 构建 SCSI UPIU(UFS 协议单元)数据包ufshcd_comp_scsi_upiu(hba, lrbp);// 映射 Scatter-Gather 列表,准备传输数据err = ufshcd_map_sg(hba, lrbp);if (err) {// 如果映射失败,释放 UFS 资源并退出ufshcd_release(hba);goto out;}// 如果启用了多队列 (MCQ),则将请求映射到硬件队列if (is_mcq_enabled(hba))hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(cmd));// 发送 UFS 命令,执行传输ufshcd_send_command(hba, tag, hwq);out:// 如果需要触发错误处理程序,进行调度if (ufs_trigger_eh(hba)) {unsigned long flags;// 锁定主机的自旋锁以安全调度错误处理程序spin_lock_irqsave(hba->host->host_lock, flags);ufshcd_schedule_eh_work(hba); // 调度错误处理工作spin_unlock_irqrestore(hba->host->host_lock, flags);}// 返回错误代码(如果有)return err;
}

主控与UFS驱动的交互

  • 传入的SCSI 命令会写入到 UFS 主控寄存器中。
  • 存储命令后进一步执行命令,与存储介质通信,执行具体的读写操作。
  • **状态反馈:**操作完成时,UFS 主控会通过中断或者状态寄存器通知UFS操作结果。

数据返回和错误处理

数据返回:如果命令执行成功,数据会通过UFS 主控返回 ufs驱动,驱动则将数据放到缓冲区,通知SCSI 子系统完成。

**错误处理:**设备没有空闲空间,UFS 报告错误状态,SCSI子系统重新执行或终止请求。

SCSI 子系统传递到上层

其中的过程应该是 块设备—>文件系统—>**应用程序,**类似U型锁一样往复从底层到上层。

详细文件构造过程

用户空间:open()** 系统调用**

在用户空间,应用程序调用 open("filename", O_CREAT | O_RDWR, 0644)。这里的 O_CREAT 标志告诉系统要创建文件。此调用通过 glibc 传递到内核,进入 VFS 层处理。

VFS 层:调用 open() 方法

VFS 层解析路径,并在目标目录中检查文件是否存在:

  • 如果文件不存在,则调用文件系统特定的 create 方法(如 EXT4 文件系统的 ext4_create)来创建文件。
  • 如果文件系统支持 journaling(如 EXT4),会在 journal 中记录创建文件的元数据操作。
  1. 文件系统驱动层:更新元数据

具体文件系统驱动(如 EXT4)负责管理和更新文件元数据,包括文件的 inode、目录项等:

  • 分配 inode:调用 inode 分配函数分配一个新的 inode。
  • 更新目录项:在父目录的目录表中添加一个新的条目,指向新创建的文件 inode。
  • 提交元数据更新:如果文件系统使用 journaling,则会将元数据变更提交到 journal 中,并在适当时写入磁盘。

块层:分配并写入数据块

文件系统驱动调用块层,将分配给文件的 inode 及数据块标记为已使用。然后数据写入请求被传递到块层,由块设备驱动负责分配块并将数据写入存储设备。

SCSI 子系统:封装请求并调度

块层的请求被传递到 SCSI 子系统。在这里,块 I/O 请求会被封装为 SCSI 命令。SCSI 子系统负责:

  • 命令封装:将 I/O 请求转换成合适的 SCSI 命令,如 WRITE
  • 命令调度:根据 I/O 调度算法(如 CFQ、Deadline 等)安排命令的执行顺序。
  • 错误处理:如果命令执行失败,SCSI 子系统可以重试请求或返回错误。

UFS 驱动**:处理 SCSI 命令

SCSI 子系统将封装好的 SCSI 命令传递给 UFS 驱动层。UFS 驱动会执行以下步骤:

  • 解析命令:UFS 驱动解析 SCSI 命令,将其转换为 UFS 协议(UPIU)命令。
  • 发送命令:UFS 驱动将 UPIU 命令通过寄存器写入 UFS 主控(Host Controller),启动数据传输。
  • 等待传输完成:UFS 主控完成操作后会通过中断通知 UFS 驱动。
  • 状态返回:UFS 驱动解析状态并将结果返回给 SCSI 子系统。

UFS 存储设备:执行写入操作

最终,UFS 主控接收并处理 UPIU 命令,UFS 存储设备执行数据写入操作,并返回状态信息(成功或错误),将结果返回给 UFS 驱动。

返回结果

  • UFS 驱动将操作结果返回给 SCSI 子系统。
  • SCSI 子系统通知块层请求已完成,或者进行错误重试。
  • 块层通知文件系统写入成功,文件系统驱动层更新状态。
  • VFS 层完成文件创建过程,将成功结果返回给用户空间应用。

小结

我们再回顾一下创建文件的整体流程吧,从用户态到硬件层起始并没有我们想象的哪么简单,需要涉及到用户端—>系统调用(open or write)—>文件系统(vfs)—>实际文件系统(f2fs_open or f2fs_write)—>块设备处理-封装IO请求(封装 IO)—>SCSI—> UFS ,真的再一次感受代码改变世界。
在这里插入图片描述

相关文章:

SCSI驱动与 UFS 驱动交互概况

SCSI子系统概况 SCSI&#xff08;Small Computer System Interface&#xff09;子系统是 Linux 中的一个模块化框架&#xff0c;用于提供与存储设备的通用接口。通过 SCSI 子系统&#xff0c;可以支持不同类型的存储协议&#xff08;如 UFS、SATA、SAS&#xff09;&#xff0c…...

软件工程实践项目:人事管理系统

一、项目的需求说明 通过移动设备登录app提供简单、方便的操作。根据公司原来的考勤管理制度&#xff0c;为公司不同管理层次提供相应的权限功能。通过app上面的各种标准操作&#xff0c;考勤管理无纸化的实现&#xff0c;使公司的考勤管理更加科学规范&#xff0c;从而节省考…...

不使用三方软件,win系统下禁止单个应用联网能力的详细操作教程

本篇文章主要讲解&#xff0c;在win系统环境下&#xff0c;禁止某个应用联网能力的详细操作教程&#xff0c;通过本教程您可以快速掌握自定义对单个程序联网能力的限制和禁止。 作者&#xff1a;任聪聪 日期&#xff1a;2024年10月30日 步骤一、按下win按键&#xff08;四个小方…...

近似线性可分支持向量机的原理推导

近似线性可分的意思是训练集中大部分实例点是线性可分的&#xff0c;只是一些特殊实例点的存在使得这种数据集不适用于直接使用线性可分支持向量机进行处理&#xff0c;但也没有到完全线性不可分的程度。所以近似线性可分支持向量机问题的关键就在于这些少数的特殊点。 相较于…...

Golang开发环境

Golang开发环境搭建 Go 语言开发包 国外&#xff1a;https://golang.org/dl/ 国内(推荐)&#xff1a; https://golang.google.cn/dl/ 编辑器 Golang:https://www.jetbrains.com/go/ Visual Studio Code: https://code.visualstudio.com/ 搭建 Go 语言开发环境&#xff0c;需要…...

测试华为GaussDB(DWS)数仓,并通过APISQL快速将(表、视图、存储过程)发布为API

华为数据仓库服务 数据仓库服务&#xff08;Data Warehouse Service&#xff0c;简称DWS&#xff09;是一种基于公有云基础架构和平台的在线数据处理数据库&#xff0c;提供即开即用、可扩展且完全托管的分析型数据库服务。DWS是基于华为融合数据仓库GaussDB产品的云原生服务&a…...

使用GetX实现GetPage中间件

前言 GetX 中间件&#xff08;Middleware&#xff09;是 GetX 框架中的一种机制&#xff0c;用于在页面导航时对用户进行权限控制、数据预加载、页面访问条件设置等。通过使用中间件&#xff0c;可以有效地控制用户的访问流程&#xff0c;并在适当条件下引导用户到所需页面。 这…...

Navicat 17 功能简介 | SQL 预览

Navicat 17 功能简介 | SQL 预览 随着 17 版本的发布&#xff0c;Navicat 也带来了众多的新特性&#xff0c;包括兼容更多数据库、全新的模型设计、可视化智能 BI、智能数据分析、可视化查询解释、高质量数据字典、增强用户体验、扩展MongoDB 功能、轻松固定查询结果、便捷URI …...

ubuntu、Debian离线部署gitlab

一、软件包下载 gitlab安装包下载链接 ubuntu&#xff1a; ubuntu/focal 适用于 ubuntu20系列 ubuntu/bionic 适用于 ubuntu18 系列 Debian&#xff1a; debian/buster 适用于 Debian10系列 debian/bullseye 适用于 Debian11、12系列 二、安装gitlab ubuntu需要安装一些环境…...

数据库编程 SQLITE3 Linux环境

永久存储程序数据有两种方式&#xff1a; 用文件存储用数据库存储 对于多条记录的存储而言&#xff0c;采用文件时&#xff0c;插入、删除、查找的效率都会很差&#xff0c;为了提高这些操作的效率&#xff0c;有计算机科学家设计出了数据库存储方式 一、数据库 数据库的基本…...

独孤思维:总有一双眼睛默默观察你做副业

01 独孤昨天在陪伴群&#xff0c;分享了近期小白做副业的一些困扰。 并且以自己经历作为案例&#xff0c;分享了一些经验和方法。 最后顺势推出xx博主的关于365条赚钱信息小报童专栏。 订阅后&#xff0c;可以开拓副业赚钱思路&#xff0c;避免走一些弯路。 甚至于&#x…...

医院信息化与智能化系统(10)

医院信息化与智能化系统(10) 这里只描述对应过程&#xff0c;和可能遇到的问题及解决办法以及对应的参考链接&#xff0c;并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图&#xff0c;可以试试PlantUML&#xff0c;告诉GPT你的文件结构&#xff0c;让他给你对应…...

基于YOLO11/v10/v8/v5深度学习的危险驾驶行为检测识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…...

Flink CDC系列之:学习理解核心概念——Transform

Flink CDC系列之&#xff1a;学习理解核心概念——Transform Transform参数元数据字段函数比较函数逻辑函数字符串函数时间函数条件函数 示例添加计算列参考元数据列使用通配符投影所有字段添加过滤规则重新分配主键重新分配分区键指定表创建配置分类映射用户定义函数已知限制 …...

MyBatis-Plus:简化 CRUD 操作的艺术

一、关于MyBatis-Plus 1.1 简介 MyBatis-Plus 是一个基于 MyBatis 的增强工具&#xff0c;它旨在简化 MyBatis 的使用&#xff0c;提高开发效率。 ​ ‍ ‍ ‍ ​ ‍ 关于Mybatis 简介 MyBatis 是一款流行的 Java 持久层框架&#xff0c;旨在简化 Java 应用程序与数…...

Windows on ARM编译安装openBLAS

Windows on ARM编译安装openBLAS 要求下载源码OpenBLAS可以使用LLVM工具链(clang-cl和flang)从源代码为Windows on ARM(WoA)进行构建。v0.3.24版本(预构建包)的构建和测试已通过。 要求 LLVM:版本需大于等于17.0.4 LLVM版本16及以下会生成冲突的符号(如_QQ*等)。 LL…...

FPGA编程语言VHDL与Verilog的比较分析!!!

VHDL&#xff08;VHSIC硬件描述语言&#xff09;和Verilog都是用于硬件描述和FPGA编程的工业标准语言。它们在语法和设计理念上存在一些差异&#xff0c;以下是两者的比较分析&#xff1a; 1. 历史背景 VHDL&#xff1a; 开发于1980年代初期&#xff0c;最初用于美国国防部的…...

C语言——八股文(笔试面试题)

1、 什么是数组指针&#xff0c;什么是指针数组&#xff1f; 数组指针&#xff1a;指向数组的指针 指针数组&#xff1a;数组中的元素都是指针 2、 什么是位段&#xff0c;什么是联合体 位段&#xff08;Bit Field&#xff09;&#xff1a;在C语言中&#xff0c;允许在一个整数…...

解决 Oracle 数据库错误 ORA-12516:监听器无法找到匹配协议栈的处理程序

在使用 Oracle 数据库时&#xff0c;有时会遇到错误 ORA-12516&#xff0c;这个错误表明 Oracle 数据库的监听器无法为新的连接请求找到一个可用的处理程序&#xff0c;这通常是因为达到了连接数上限、配置问题或资源限制。本文将详细介绍如何解决这个问题。 一、错误描述 当…...

Flarum:简洁而强大的开源论坛软件

Flarum简介 Flarum是一款开源论坛软件&#xff0c;以其简洁、快速和易用性而闻名。它继承了esoTalk和FluxBB的优良传统&#xff0c;旨在提供一个不复杂、不臃肿的论坛体验。Flarum的核心优势在于&#xff1a; 快速、简单&#xff1a; Flarum使用PHP构建&#xff0c;易于部署&…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?

在现代前端开发中&#xff0c;Utility-First (功能优先) CSS 框架已经成为主流。其中&#xff0c;Tailwind CSS 无疑是市场的领导者和标杆。然而&#xff0c;一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...