Linux Scsi子系统框架介绍( 七 )


它也会创建一个同名的sg device挂在自定义的”scsi_generic” class上(没有什么特别作用) 。
sg作用:

  • Sg存在的唯一目的 , 是使用ioctl命令 , 例如rpmb的操作 , FFU固件升级等操作 , 都是通过ioctl方式完成 。
  • 由于无论sg还是sd , 还是别的什么scsi外设驱动创建出来用户态设备节点 , 最终都是通过lun对应的request_queue来完成发送scsi命令 , 所以sg能做的事情 , 其它节点也能做 , 因此有的平台没有打开sg编译开关 。

Linux Scsi子系统框架介绍

文章插图
 
四、数据链表结构硬件拓扑结构是一个树形 。在linuxscsi子系统里面 , host , target , lun对应的scsi_host, scsi_target, scsi_device也是一个树形链表结构 , 如下图:
Linux scsi子系统中的所有list链表操作都是按照这张图中的数据结构处理的 。
 
Linux Scsi子系统框架介绍

文章插图
 
scsi.c代码很多是围绕这个结构体进行操作的 , 例如:
shost_for_each_device
starget_for_each_device
scsi_device_lookup_by_target
scsi_device_lookup
__scsi_iterate_devices
具体实现 , 大家可以自己研究 , 对照这张图 , 代码看起来不会很难 。
 
五、总结:
  • Linux中复杂的驱动子系统的设计基本类似与scsi子系统 , 先有一个物理设备拓补模型 , 再设计对应的软件驱动模型 。
  • 有时为了软件操作有条理 , 或者为了软件方便扩展 , 也或者为了代码解耦 , 可以把物理设备拓补模型进行虚拟扩展 。例如:1上述虚拟出的target设备. 2 pcie也会把抽象的bus信号线虚拟出一个pci_bus class设备等等 。目的就是软件上采用分级驱动形式 , 把复杂的操作简化 。
  • 设备模型建好后 , 再实现设备扫描和PM相关的功能 , 各层驱动负责各层操作 , 尽量不越界操作 , 减少代码耦合 。例如sd.c不关心device是怎么放到scsi总线上来的(这个device可能是某个pcie插槽接的板卡 , 板卡再外接的一个外设;也可能是soc ufs控制器上的外设)sd.c驱动只管基于scsi command做好自己分内的操作就可以兼容这些设备 。
  • 外部硬件的连接方式像搭积木 , 分级驱动也可以以最小代价像积木一样应对硬




推荐阅读