SCSI子系统基础学习笔记 (之UFS子系统) - 2.1UFS子系统初始化之ufs_qcom_probe

本文详细介绍了UFS子系统初始化的过程,从platform_device注册到ufs_qcom_probe函数执行,包括ufshcd_alloc_host和ufshcd_init的步骤。内容涵盖时钟、电源、中断资源的获取与配置,以及Scsi_host的创建和ufs_controller的初始化,涉及到设备节点扫描、DTS解析、工作队列和中断处理等关键环节。

1. 前言

本专题我们开始学习SCSI子系统的相关内容。本专题主要参考了《存储技术原理分析》、ULA、ULK的相关内容。本专题主要以硬件UFS为例,记录SCSI子系统的框架流程。本文是UFS子系统初始化部分。
如何发现有哪些场景?主要可以从如下几个角度:

  1. 初始化和退出;
  2. 线程处理函数;
  3. 调用中间层导出函数的流程;
  4. 调用底层回调函数的;
  5. 顶层使用者的动作

ufs的初始化主要包含了如下几部分:

  1. ufshcd_pltfrm_probe的执行过程
    主要完成ufs host的初始化,分配scsi_host结构体,并完成host, channel, target, device的扫描,为发现的每一个LUN 创建scsi_device,同时为每一个scsi_devcie创建了request_queue

  2. sd_probe的执行过程
    在每一个scsi_device->dev注册时,会引发sd.c中的sd_probe的执行,它会在每一次执行时创建gendisk,并通过add_gendisk添加到系统

本文主要介绍ufs_qcom_probe的执行过程

kernel版本:5.10
平台:arm64

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

2.ufs_qcom_probe

static int ufs_qcom_probe(struct platform_device *pdev)
	|--struct ufs_hba *hba;
	|  void __iomem *mmio_base; 
	|  struct device *dev = &pdev->dev;
	|--ufshcd_pltfrm_init(pdev, &ufs_hba_qcom_vops);
			|--mmio_base = devm_platform_ioremap_resource(pdev, 0);
			|--irq = platform_get_irq(pdev, 0);
			|--ufshcd_alloc_host(dev, &hba); 
			|--hba->vops = vops;
			|--ufshcd_parse_clock_info(hba);
			|--ufshcd_parse_regulator_info(hba);
			|--ufshcd_init_lanes_per_dir(hba);
			|--ufshcd_init(hba, mmio_base, irq);
			|--platform_set_drvdata(pdev, hba);
			|--pm_runtime_set_active(&pdev->dev);
			\--pm_runtime_enable(&pdev->dev);

由于在dts中设置了UFS的设备节点,那么在kenrel初始化时会扫描设备节点为每个设备节点注册platform_device,在ufs-qcom.c中通过宏module_platform_driver(ufs_qcom_pltform);定义了init函数和exit函数,实际会执行platform_driver_register(ufs_qcom_pltform),由于与platform_device的compatible匹配(均为qcom,ufshc),因此会触发ufs_qcom_probe执行。最主要的会执行ufshcd_pltfrm_init(pdev, &ufs_hba_qcom_variant)函数,它负责获取IO资源,中断号,通过scsi_host_alloc为Scsi_host及私有数据空间hba分配空间,同时通过解析DTS中的属性值初始化hba相关成员,最后通过ufshcd_init对ufs controller进行初始化,并对链接的ufs device进行扫描

  1. devm_platform_ioremap_resource:主要对io资源进行地址映射

  2. platform_get_irq:获取中断号,此处返回的是虚拟中断号

  3. ufshcd_alloc_host:分配ufs控制器,此处主要调用了scsi_host_alloc(&ufshcd_driver_template,sizeof(struct ufs_hba))来分配Scsi_host空间,同时也一起为ufs host的私有数据struct ufs_hba分配空间(可参考添加磁盘章节),并对scsi_host执行基本的初始化。ufshcd_driver_template为传入的参数,它在ufshcd.c中定义,它定义了scsi host所实现的基本模板函数。

  4. hba->var = var:获取ufs的操作函数集,此处的var为全局的struct ufs_hba_variant ufs_hba_qcom_variant变量,其中主要的成员为ufs_hba_variant_ops函数集,这些函数集定义在ufs-qcom.c中,可以看出这些ops主要是关于时钟和电源相关的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值