1.6.2 scsi设备驱动体系架构

从这一层开始,整个文件读写的中心将由request转向scsi的命令结构scsi_cmnd。那么这个命令结构到底是怎么一回事呢,这还得从SCSI架构谈起。SCSI 实现了一种客户机/服务器风格的通信架构,发起者向目标设备发送命令请求。该目标处理此请求并向发起者返回响应。发起者可以是托管计算机中的一个 SCSI 设备,而 SCSI 目标则可以是一个磁盘、光盘和磁带设备或特殊设备(比如箱体设备)。

这里要提到一个概念——Lower Level Device(LDD):在最低层的是一组驱动器,称为 SCSI 低层驱动器。它们是一些可与物理设备(比如 HBA)链接的特定驱动器。LLD 提供了自公共中间层到特定于设备的 HBA 的一种抽象。每个 LLD 都提供了到特定底层硬件的接口,但所使用的到中间层的接口却是一组标准接口。

较低层包含大量代码,原因是它要负责处理各种不同的 SCSI 适配器类型。例如,Fibre Channel 协议包含了针对 Emulex 和 QLogic 的各种适配器的 LLD。面向 Adaptec 和 LSI 的 SAS 适配器的 LLD 也包括在内。

与存储相关的 SCSI 命令一般是在 SCSI Architecture Model (SAM)、SCSI Primary Commands (SPC) 和 SCSI Block Commands (SBC) 中定义的:

l  SAM:定义SCSI 系统模型、SCSI 标准集的功能性分区,以及适用于所有 SCSI 实现和实现标准的需求。

l  SPC:定义:对所有 SCSI 设备模型通用的行为。

l  SBC:定义命令集扩展,以方便操作 SCSI 直接访问块设备。

每个 SCSI 命令都由 Command Descriptor Block (CDB) 描述,它定义 SCSI 设备执行的操作。SCSI 命令涉及到用于向 SCSI 设备传输数据(或从中输出数据)的数据命令,以及用于设置 SCSI 设备的配置参数的非数据命令。

典型的CDB格式如下图所示:

 

位 7

位 6

位 5

位 4

位 3

位 2

位 1

位 0

字节 0

Operation code = 12h

字节 1

LUN

Reserved

EVPD

字节 2

Page code

字节 3

Reserved

字节 4

Allocation length

字节 5

Control

如果 EVPD 参数位(用于启用关键产品数据)为 0 并且 Page Code 参数字节为 0,那么目标将返回标准命令数据(如inquiry)。如果 EVPD 参数为 1,那么目标将返回对应 page code 字段的特定于供应商的数据。

scsi_cmnd结构中的cmnd[MAX_COMMAND_SIZE]数组就是这个CDB的内容。我们看到这个数组虽然最大可有16个元素,每个元素1字节,但是我们仅仅用了其中6个元素,用来存放CDB,其中cmnd[0]最为重要,对应scsi操作码。所有的scsi操作码都有定义,在include/scsi/scsi.h中:

#define TEST_UNIT_READY       0x00

#define REZERO_UNIT           0x01

#define REQUEST_SENSE         0x03

#define FORMAT_UNIT           0x04

#define READ_BLOCK_LIMITS     0x05

#define REASSIGN_BLOCKS       0x07

#define INITIALIZE_ELEMENT_STATUS 0x07

#define READ_6                0x08

#define WRITE_6               0x0a

#define SEEK_6                0x0b

#define READ_REVERSE          0x0f

#define WRITE_FILEMARKS       0x10

#define SPACE                 0x11

#define INQUIRY               0x12

#define RECOVER_BUFFERED_DATA 0x14

#define MODE_SELECT           0x15

#define RESERVE               0x16

#define RELEASE               0x17

#define COPY                  0x18

#define ERASE                 0x19

#define MODE_SENSE            0x1a

#define START_STOP            0x1b

#define RECEIVE_DIAGNOSTIC    0x1c

#define SEND_DIAGNOSTIC       0x1d

#define ALLOW_MEDIUM_REMOVAL  0x1e

#define SET_WINDOW            0x24

#define READ_CAPACITY         0x25

#define READ_10               0x28

#define WRITE_10              0x2a

#define SEEK_10               0x2b

#define POSITION_TO_ELEMENT   0x2b

#define WRITE_VERIFY          0x2e

#define VERIFY                0x2f

#define SEARCH_HIGH           0x30

#define SEARCH_EQUAL          0x31

#define SEARCH_LOW            0x32

#define SET_LIMITS            0x33

#define PRE_FETCH             0x34

#define READ_POSITION         0x34

#define SYNCHRONIZE_CACHE     0x35

#define LOCK_UNLOCK_CACHE     0x36

#define READ_DEFECT_DATA      0x37

#define MEDIUM_SCAN           0x38

#define COMPARE               0x39

#define COPY_VERIFY           0x3a

#define WRITE_BUFFER          0x3b

#define READ_BUFFER           0x3c

#define UPDATE_BLOCK          0x3d

#define READ_LONG             0x3e

#define WRITE_LONG            0x3f

#define CHANGE_DEFINITION     0x40

#define WRITE_SAME            0x41

#define READ_TOC              0x43

#define LOG_SELECT            0x4c

#define LOG_SENSE             0x4d

#define MODE_SELECT_10        0x55

#define RESERVE_10            0x56

#define RELEASE_10            0x57

#define MODE_SENSE_10         0x5a

#define PERSISTENT_RESERVE_IN 0x5e

#define PERSISTENT_RESERVE_OUT 0x5f

#define REPORT_LUNS           0xa0

#define MOVE_MEDIUM           0xa5

#define EXCHANGE_MEDIUM       0xa6

#define READ_12               0xa8

#define WRITE_12              0xaa

#define WRITE_VERIFY_12       0xae

#define SEARCH_HIGH_12        0xb0

#define SEARCH_EQUAL_12       0xb1

#define SEARCH_LOW_12         0xb2

#define READ_ELEMENT_STATUS   0xb8

#define SEND_VOLUME_TAG       0xb6

#define WRITE_LONG_2          0xea

#define READ_16               0x88

#define WRITE_16              0x8a

#define VERIFY_16            0x8f

#define SERVICE_ACTION_IN     0x9e

/* values for service action in */

#define    SAI_READ_CAPACITY_16  0x10

/* Values for T10/04-262r7 */

#define    ATA_16                0x85    /* 16-byte pass-thru */

#define    ATA_12                0xa1    /* 12-byte pass-thru */

我们列出最常使用的命令:

命令

描述

INQUIRY

请求目标设备的摘要信息

TEST_UNIT_READY

检测目标设备是否准备好进行传输

READ_6

从 SCSI 目标设备传输数据

WRITE_6

向 SCSI 目标设备传输数据

REQUEST_SENSE

请求最后一个命令的检测数据

READ_CAPACITY

获得存储容量信息

所有 SCSI 命令都要以操作代码的第一个字节为开端,以表明它所代表的操作。并且所有 SCSI 命令都要包含一个控制字节。这个字节通常是该命令的最后一个字节,用于表示与供应商相关的信息等等。

scsi_cmnd 结构就完全是SCSI记录的抽象,不仅cmnd数组字段记录了命令描述块 (CDB);还有用于感测数据缓存 (SENSE BUFFER)的sense_buffer字段,以及用于存放IO 超时时间等 SCSI 相关的信息和 SCSI 子系统处理命令需要的一些其他信息的字段,如回调函数等。

来自include/scsi/scsi_cmnd.h:

struct scsi_cmnd {

struct scsi_device *device;

struct list_head list;  /* scsi_cmnd participates in queue lists */

struct list_head eh_entry; /* entry for the host eh_cmd_q */

int eh_eflags;         /* Used by error handlr */

void (*done) (struct scsi_cmnd *);       /* Mid-level done function */

unsigned long serial_number;

unsigned long jiffies_at_alloc;

int retries;

int allowed;

int timeout_per_command;

unsigned char cmd_len;

enum dma_data_direction sc_data_direction;

/* These elements define the operation we are about to perform */

#define MAX_COMMAND_SIZE       16

unsigned char cmnd[MAX_COMMAND_SIZE];

unsigned request_bufflen;      /* Actual request size */

struct timer_list eh_timeout;  /* Used to time out the command. */

void *request_buffer;            /* Actual requested buffer */

/* These elements define the operation we ultimately want to perform */

unsigned short use_sg;   /* Number of pieces of scatter-gather */

unsigned short sglist_len;      /* size of malloc'd scatter-gather list */

unsigned underflow;

unsigned transfersize;

int resid;

struct request *request;

#define SCSI_SENSE_BUFFERSIZE        96

unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];

/* obtained by REQUEST SENSE when

* CHECK CONDITION is received on original

* command (auto-sense) */

void (*scsi_done) (struct scsi_cmnd *);

struct scsi_pointer SCp;  /* Scratchpad used by some host adapters */

unsigned char *host_scribble;

int result;        /* Status code from lower level driver */

unsigned char tag;  /* SCSI-II queued command tag */

unsigned long pid;  /* Process ID, starts at 0. Unique per host. */

};

scsi设备驱动体系架构相关推荐

  1. ceph存储 scsi设备驱动体系架构

    scsi设备驱动体系架构 从这一层开始,整个文件读写的中心将由request转向scsi的命令结构scsi_cmnd.那么这个命令结构到底是怎么一回事呢,这还得从SCSI架构谈起.SCSI 实现了一种 ...

  2. Linux块设备驱动(二)————块设备的体系架构

    块设备的体系架构从上到下依次为VFS虚拟文件系统.磁盘缓冲.各种类型的磁盘系统.通用块设备层.I/O调度层(优化访问上层的请求(读写请求)).块设备驱动层.块设备硬件层. 1.虚拟文件系统(VFS) ...

  3. linux 内核驱动模型,linux设备驱动模型架构分析 一

    linux设备驱动模型架构分析 一 发布时间:2018-07-04 15:14, 浏览次数:584 , 标签: linux 概述 LDD3中说:"Linux内核需要一个对系统结构的一般性描述 ...

  4. Linux设备驱动开发基础

    1.驱动概述和开发环境搭建 1.1驱动设备的作用 对设备驱动最通俗的解释就是"驱动硬件设备行动".驱动与底层硬件直接打交道,按照硬件设备的具体工作方式,读写设备的寄存器,完成设备的 ...

  5. 《Linux 设备驱动开发详解(第2版)》——1.4 Linux设备驱动

    本节书摘来自异步社区<Linux 设备驱动开发详解(第2版)>一书中的第1章,第1.1节,作者:宋宝华著,更多章节内容可以访问云栖社区"异步社区"公众号查看 1.4 L ...

  6. 《Linux设备驱动开发详解(第2版)》隆重出版

    Linux设备驱动开发详解(第2版)(前一版狂销3万册,畅销书最新升级) [新品] 点击看大图     基本信息 * 作者: 宋宝华       * 出版社:人民邮电出版社     * ISBN:97 ...

  7. scsi总线驱动的初始化

    1.6.1 scsi总线驱动的初始化 块设备底层驱动的核心是scsi总线层驱动,在总线层驱动之上为各种不同的scsi设备驱动,在总线层驱动之下为scsi host驱动.其在内核中的位置如下图所示: 前 ...

  8. 转载:谢谢原作者:块设备驱动实战基础篇一 (170行代码构建一个逻辑块设备驱动)

    1   内核块设备驱动基础学习与实战 1.1 设备驱动IO架构初探 操作系统是如何将数据读到缓冲区的,发生了什么?我们带着这样的问题,粗略走一下read调用系统过程,希望这个初探,可以唤起大家研究操作 ...

  9. Linux设备驱动开发概述

    作者:宋宝华 email:author@linuxdriver.cn 在过去这些年,Linux已经成功应用于服务器和桌面系统,而近年来,随着嵌入式系统应用的持续升温,Linux也开始广泛应用于嵌入式领 ...

最新文章

  1. android mapping.txt,Android根据mapping.txt还原混淆的代码
  2. 2016可信云大会进入倒计时 顶级“参会攻略”强势来袭
  3. jquery的DOM节点操作(替换元素节点)
  4. 支持向量机的前世与今生
  5. python_day9 回调函数
  6. CSS学习总结(3)——CSS文本样式(属性)
  7. java课时,java学习笔记_课时一
  8. 高手对中科院考博英语的体会
  9. wxFormBuilder + wxPython手撸丑陋计算器
  10. 航空公司客户价值分析R语言实现
  11. 点赞 分数 20作者 陈越单位 浙江大学
  12. 华为云服务器如何使用
  13. WPF教程(二) WPF vs WinForms
  14. subprocess模块call的用法
  15. thinkphp6 404找不到网页错误常见情况总结(持续更新)
  16. java毕业设计-篮球资讯网站-源码+lw文档+mybatis+系统+mysql数据库+调试
  17. 【总线】一文看懂 UART 通信协议
  18. 一款功能强大的IP查询工具!
  19. 盛元广通高校实验室管理系统
  20. excel行列互换_办公软件操作技巧043:如何在excel中实现行列转置

热门文章

  1. 云计算平台与传统平台的区别是什么?怎么理解?
  2. VUE仿猫眼电影总结(一)
  3. 如何用乌班图(Ubuntu)制作 linux 系统 U盘启动盘
  4. 解决anaconda下载pytorch慢问题(清华镜像源)
  5. 2、使用Xcode9创建第一个IOS界面
  6. ADDS:启用 Advanced Offline Files
  7. 发现一个名为“Douyu”的国人项目
  8. 人工智能原理复习 | 课程背景
  9. Java day16:代码作业(人才管理系统)
  10. 我问 ChatGPT Java 编程语言的优缺点是什么?它这么回答……