SCSI 介面指南¶
- 作者:
James Bottomley
- 作者:
Rob Landley
介紹¶
協議與匯流排¶
很久以前,小型計算機系統介面定義了一種並行 I/O 匯流排和一種資料協議,用於將各種外圍裝置(磁碟驅動器、磁帶驅動器、調變解調器、印表機、掃描器、光碟機、測試裝置和醫療裝置)連線到主機。
儘管舊的並行(快速/寬/超寬)SCSI 匯流排已基本不再使用,但 SCSI 命令集的使用範圍比以往任何時候都更廣泛,可以透過多種不同的匯流排與裝置通訊。
SCSI 協議是一種大端對等基於資料包的協議。 SCSI 命令長度為 6、10、12 或 16 個位元組,通常後跟關聯的資料有效負載。
SCSI 命令幾乎可以透過任何型別的匯流排傳輸,並且是連線到 USB、SATA、SAS、光纖通道、FireWire 和 ATAPI 裝置的儲存裝置的預設協議。 SCSI 資料包也通常透過 InfiniBand、TCP/IP (iSCSI),甚至 並行埠 進行交換。
Linux SCSI 子系統的設計¶
SCSI 子系統使用三層設計,包括上層、中層和下層。 每個涉及 SCSI 子系統的操作(例如從磁碟讀取扇區)都會使用每一層的驅動程式:一個上層驅動程式、一個下層驅動程式和 SCSI 中間層。
SCSI 上層以 I/O 和 ioctl() 的塊和字元裝置節點的形式提供使用者空間和核心之間的介面。 SCSI 下層包含特定硬體裝置的驅動程式。
兩者之間是 SCSI 中間層,類似於網路路由層,例如 IPv4 堆疊。 SCSI 中間層在上面的 /dev 節點和下面的相應裝置之間路由基於資料包的資料協議。 它管理命令佇列,提供錯誤處理和電源管理功能,並響應 ioctl() 請求。
SCSI 上層¶
上層透過提供裝置節點來支援使用者核心介面。
sd (SCSI 磁碟)¶
sd (sd_mod.o)
sr (SCSI CD-ROM)¶
sr (sr_mod.o)
st (SCSI 磁帶)¶
st (st.o)
sg (SCSI 通用)¶
sg (sg.o)
ch (SCSI 媒體更換器)¶
ch (ch.c)
SCSI 中間層¶
SCSI 中間層實現¶
include/scsi/scsi_device.h¶
-
struct scsi_vpd¶
SCSI 重要產品資料
定義:
struct scsi_vpd {
struct rcu_head rcu;
int len;
unsigned char data[];
};
成員
rcu用於
kfree_rcu()。len**data** 的長度(以位元組為單位)。
dataVPD 資料,如各種 T10 SCSI 標準文件中所定義。
-
shost_for_each_device¶
shost_for_each_device (sdev, shost)
迭代主機的所有裝置
引數
sdev用作遊標的
struct scsi_deviceshost要迭代的
struct scsi_host
描述
迭代器,返回連線到 **shost** 的每個裝置。 此迴圈獲取每個裝置上的引用並在末尾釋放它。 如果你跳出迴圈,則必須呼叫 scsi_device_put(sdev)。
-
__shost_for_each_device¶
__shost_for_each_device (sdev, shost)
迭代主機的所有裝置(已解鎖)
引數
sdev用作遊標的
struct scsi_deviceshost要迭代的
struct scsi_host
描述
迭代器,返回連線到 **shost** 的每個裝置。 它不獲取 scsi_device 上的引用,因此整個迴圈必須受 shost->host_lock 保護。
注意
使用它的唯一原因是需要訪問中斷上下文中的裝置列表。 否則,你真的想要使用 shost_for_each_device。
-
int scsi_device_supports_vpd(struct scsi_device *sdev)¶
測試裝置是否支援 VPD 頁面
引數
struct scsi_device *sdev要測試的
struct scsi_device
描述
如果設定了“try_vpd_pages”標誌,則它優先。 否則,如果 SCSI 級別至少為 SPC-3 並且未設定“skip_vpd_pages”,我們將假定支援 VPD 頁面。
drivers/scsi/scsi.c¶
SCSI 中間層的主檔案。
-
int scsi_change_queue_depth(struct scsi_device *sdev, int depth)¶
更改裝置的佇列深度
引數
struct scsi_device *sdev有問題的 SCSI 裝置
int depth允許排隊到驅動程式的命令數
描述
設定裝置佇列深度並返回新值。
-
int scsi_track_queue_full(struct scsi_device *sdev, int depth)¶
跟蹤 QUEUE_FULL 事件以調整佇列深度
引數
struct scsi_device *sdev有問題的 SCSI 裝置
int depth此裝置上未完成的 SCSI 命令的當前數量,不包括返回為 QUEUE_FULL 的命令。
描述
- 此函式將跟蹤特定的
SCSI 裝置上的連續 QUEUE_FULL 事件,以確定是否以及何時需要調整裝置上的佇列深度。
鎖定狀態:條目上未持有任何鎖
返回
- 0 - 不需要更改,>0 - 將佇列深度調整為此新深度,
- -1 - 使用 host->cmd_per_lun 作為未標記的命令深度回退到未標記的操作
註釋
底層驅動程式可以隨時呼叫它,我們將執行
- “正確的事”。 我們是中斷上下文安全的。
“正確的事情”。我們是中斷上下文安全的。
-
int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, int buf_len)¶
從 SCSI 裝置獲取重要產品資料
引數
struct scsi_device *sdev要詢問的裝置
u8 page要返回的 Vital Product Data
unsigned char *buf儲存 VPD 的位置
int buf_lenVPD 緩衝區區域中的位元組數
描述
SCSI 裝置可以選擇性地提供 Vital Product Data。 每個 VPD“頁面”都在相應的 SCSI 文件(例如 SPC、SBC)中定義。 如果裝置支援此 VPD 頁面,則此例程將使用該頁面的資料填充 **buf** 並返回 0。 如果不支援 VPD 頁面或無法檢索其內容,則返回 -EINVAL。
-
int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, unsigned int len, unsigned char opcode, unsigned short sa)¶
查明是否支援給定命令
引數
struct scsi_device *sdev要查詢的 scsi 裝置
unsigned char *buffer暫存緩衝區(長度必須至少為 20 位元組)
unsigned int len緩衝區長度
unsigned char opcode要查詢的命令的操作碼
unsigned short sa要查詢的命令的服務操作
描述
使用 REPORT SUPPORTED OPERATION CODES 檢查對使用 **opcode** 和 **sa** 標識的命令的支援。 如果命令沒有服務操作,則 **sa** 必須為 0。 如果 RSOC 失敗,則返回 -EINVAL;如果不支援該命令,則返回 0;如果裝置宣告支援該命令,則返回 1。
-
int scsi_device_get(struct scsi_device *sdev)¶
獲取對 scsi_device 的額外引用
引數
struct scsi_device *sdev要獲取引用的裝置
描述
獲取對 scsi_device 的引用並遞增底層 LLDD 模組的使用計數。 呼叫此函式時,你必須持有父 Scsi_Host 的 host_lock 或已經具有引用。
如果裝置被刪除或取消,或者 LLD 模組正在解除安裝過程中,則此操作將失敗。
-
void scsi_device_put(struct scsi_device *sdev)¶
釋放對 scsi_device 的引用
引數
struct scsi_device *sdev要釋放引用的裝置。
描述
釋放對 scsi_device 的引用並遞減底層 LLDD 模組的使用計數。 一旦最後一個使用者消失,該裝置將被釋放。
-
void starget_for_each_device(struct scsi_target *starget, void *data, void (*fn)(struct scsi_device*, void*))¶
幫助程式遍歷目標的所有裝置
引數
struct scsi_target *starget我們要迭代的裝置的目標。
void *data傳遞給每個函式呼叫的不透明資料。
void (*fn)(struct scsi_device *, void *)要在每個裝置上呼叫的函式
描述
這將遍歷 **starget** 的每個裝置。 這些裝置具有一個引用,必須透過 scsi_host_put 在跳出迴圈時釋放該引用。
-
void __starget_for_each_device(struct scsi_target *starget, void *data, void (*fn)(struct scsi_device*, void*))¶
遍歷目標的所有裝置的助手函式 (未鎖定)
引數
struct scsi_target *starget我們要迭代的裝置的目標。
void *data回撥函式 fn() 的引數
void (*fn)(struct scsi_device *, void *)為每個裝置呼叫的回撥函式
描述
此函式遍歷 starget 的每個裝置。它_不_獲取對 scsi_device 的引用,因此整個迴圈必須由 shost->host_lock 保護。
注意
驅動程式可能想要使用此函式的唯一原因是,它們需要在 irq 上下文中訪問裝置列表。否則,您真的想使用 starget_for_each_device 代替。
-
struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *starget, u64 lun)¶
查詢給定目標的裝置 (未鎖定)
引數
struct scsi_target *stargetSCSI 目標指標
u64 lunSCSI 邏輯單元號
描述
查詢具有指定 lun 的 scsi_device 以用於給定的 starget。返回的 scsi_device 沒有額外的引用。您必須在此呼叫以及對返回的 scsi_device 的任何訪問中持有主機的 host_lock。狀態為 SDEV_DEL 的 scsi_device 將被跳過。
注意
驅動程式應該使用此函式的唯一原因是,它們需要在 irq 上下文中訪問裝置列表。否則,您真的想使用 scsi_device_lookup_by_target 代替。
-
struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *starget, u64 lun)¶
查詢給定目標的裝置
引數
struct scsi_target *stargetSCSI 目標指標
u64 lunSCSI 邏輯單元號
描述
查詢具有指定 lun 的 scsi_device 以用於給定的 starget。返回的 scsi_device 有一個額外的引用,一旦您完成使用它,就需要使用 scsi_device_put 釋放該引用。
-
struct scsi_device *__scsi_device_lookup(struct Scsi_Host *shost, uint channel, uint id, u64 lun)¶
查詢給定主機的裝置 (未鎖定)
引數
struct Scsi_Host *shostSCSI 主機指標
uint channelSCSI 通道 (如果只有一個通道,則為零)
uint idSCSI 目標編號 (物理單元編號)
u64 lunSCSI 邏輯單元號
描述
查詢具有指定 channel、id、lun 的 scsi_device 以用於給定的主機。返回的 scsi_device 沒有額外的引用。您必須在此呼叫以及對返回的 scsi_device 的任何訪問中持有主機的 host_lock。
注意
驅動程式可能想要使用此函式的唯一原因是,它們需要在 irq 上下文中訪問裝置列表。否則,您真的想使用 scsi_device_lookup 代替。
-
struct scsi_device *scsi_device_lookup(struct Scsi_Host *shost, uint channel, uint id, u64 lun)¶
查詢給定主機的裝置
引數
struct Scsi_Host *shostSCSI 主機指標
uint channelSCSI 通道 (如果只有一個通道,則為零)
uint idSCSI 目標編號 (物理單元編號)
u64 lunSCSI 邏輯單元號
描述
查詢具有指定 channel、id、lun 的 scsi_device 以用於給定的主機。返回的 scsi_device 有一個額外的引用,一旦您完成使用它,就需要使用 scsi_device_put 釋放該引用。
drivers/scsi/scsicam.c¶
SCSI 通用訪問方法支援函式,用於 HDIO_GETGEO 等。
-
unsigned char *scsi_bios_ptable(struct block_device *dev)¶
從裝置的第一個扇區中讀取 PC 分割槽表。
引數
struct block_device *dev來自此裝置
描述
- 從裝置讀取第一個扇區並返回從偏移量
0x1be開始的0x42位元組。 從偏移量
0x1be開始。
返回
kmalloc(GFP_KERNEL) 記憶體中的分割槽表,如果出錯,則為 NULL。
-
bool scsi_partsize(struct block_device *bdev, sector_t capacity, int geom[3])¶
從 PC 分割槽表解析柱面/磁頭/扇區
引數
struct block_device *bdev要解析的塊裝置
sector_t capacity磁碟的大小,以扇區為單位
int geom[3]以 [hds, cylinders, sectors] 形式輸出
描述
確定用於建立分割槽表的 BIOS 對映/幾何圖形,並將結果儲存在 geom 中。
返回
失敗時為 false,成功時為 true。
-
int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip)¶
確定磁碟的柱面/磁頭/扇區幾何圖形。
引數
struct block_device *bdev哪個裝置
sector_t capacity磁碟的大小,以扇區為單位
int *ip返回值: ip[0]=heads, ip[1]=sectors, ip[2]=cylinders
描述
- 確定用於 SCSI-CAM 系統中的驅動器的 BIOS 對映/幾何圖形,並將結果儲存在 ip 中,如 HDIO_GETGEO ioctl() 所需。
SCSI-CAM 系統,根據 HDIO_GETGEO ioctl() 的要求,將結果儲存在 ip 中。
返回
失敗時為 -1,成功時為 0。
drivers/scsi/scsi_error.c¶
常見的 SCSI 錯誤/超時處理例程。
-
void scsi_schedule_eh(struct Scsi_Host *shost)¶
為 SCSI 主機安排 EH
引數
struct Scsi_Host *shost要在其上呼叫錯誤處理的 SCSI 主機。
描述
在沒有 scmd 的情況下安排 SCSI EH。
-
int scsi_block_when_processing_errors(struct scsi_device *sdev)¶
防止命令排隊。
引數
struct scsi_device *sdev我們正在執行恢復的裝置。
描述
我們阻塞直到主機退出錯誤恢復,然後檢查主機或裝置是否離線。
- 返回值
當裝置因錯誤恢復而離線時,返回 0。1 OK 繼續。
-
enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)¶
檢查 scsi cmd 感知
引數
struct scsi_cmnd *scmd要檢查感知的 Cmd。
描述
- 返回值
SUCCESS 或 FAILED 或 NEEDS_RETRY 或 ADD_TO_MLQUEUE
底層驅動程式可以隨時呼叫它,我們將執行
當檢測到延遲錯誤時,當前命令尚未執行,需要重試。
-
void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, unsigned char *cmnd, int cmnd_size, unsigned sense_bytes)¶
儲存 scsi 命令資訊作為錯誤恢復的一部分
引數
struct scsi_cmnd *scmd要劫持的 SCSI 命令結構
struct scsi_eh_save *ses用於儲存還原資訊的結構
unsigned char *cmnd要傳送的 CDB。如果不需要新的 cmnd,則可以為 NULL
int cmnd_sizecmnd 的大小(以位元組為單位)(必須 <= MAX_COMMAND_SIZE)
unsigned sense_bytes要複製的感知資料的大小。或 0(如果 != 0,則忽略 cmnd)
描述
此函式用於在重新執行之前儲存 scsi 命令資訊,作為錯誤恢復過程的一部分。如果 sense_bytes 為 0,則傳送的命令必須是不傳輸任何資料的命令。如果 sense_bytes != 0,則忽略 cmnd,並且此函式會設定 REQUEST_SENSE 命令和 cmnd 緩衝區以將 sense_bytes 讀取到 scmd->sense_buffer 中。
-
void scsi_eh_restore_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses)¶
作為錯誤恢復的一部分還原 scsi 命令資訊
引數
struct scsi_cmnd* scmd要還原的 SCSI 命令結構
struct scsi_eh_save *ses來自對 scsi_eh_prep_cmnd 的相應呼叫的已儲存資訊
描述
撤消上述 scsi_eh_prep_cmnd() 所做的任何損害。
-
void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)¶
處理 eh 完成的 cmd。
引數
struct scsi_cmnd *scmdeh 已完成的原始 SCSI cmd。
struct list_head *done_q已處理命令的佇列。
底層驅動程式可以隨時呼叫它,我們將執行
我們不想在使用我們仍在處理錯誤時使用正常的命令完成 - 它可能會導致其他命令排隊,這將擾亂我們正在做的事情。因此,我們真的想保留一個待處理命令的列表以進行最終完成,並且一旦我們準備好離開錯誤處理,我們就會真正處理完成。
-
int scsi_eh_get_sense(struct list_head *work_q, struct list_head *done_q)¶
獲取裝置感知資料。
引數
struct list_head *work_q要處理的命令佇列。
struct list_head *done_q已處理命令的佇列。
描述
看看我們是否需要請求感知資訊。如果是這樣,現在就獲取它,以便我們更好地瞭解該怎麼做。
底層驅動程式可以隨時呼叫它,我們將執行
這會產生不幸的副作用,即如果 shost 介面卡不自動請求感知資訊,我們最終會在請求它之前將其關閉。
所有驅動程式現在都應該在內部請求感知資訊,所以現在我不得不說,如果你最終進入這裡,那你就倒黴了。
- XXX: 從長遠來看,此程式碼應該消失,但這需要首先稽核所有 LLDD。
首先是所有 LLDD。
-
void scsi_eh_ready_devs(struct Scsi_Host *shost, struct list_head *work_q, struct list_head *done_q)¶
檢查裝置就緒狀態,如果未就緒則恢復。
引數
struct Scsi_Host *shost要恢復的主機。
struct list_head *work_q待處理命令的
list_head。struct list_head *done_q已處理命令的
list_head。
-
void scsi_eh_flush_done_q(struct list_head *done_q)¶
完成已處理的命令或重試它們。
引數
struct list_head *done_q已處理命令的 list_head。
-
void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)¶
報告觀察到的匯流排重置
引數
struct Scsi_Host *shost有問題的 Host
int channel觀察到重置的通道。
描述
底層驅動程式使用的實用程式函式,用於報告它們已在正在處理的總線上觀察到匯流排重置。
鎖定狀態: 必須持有主機鎖。
返回
無
底層驅動程式可以隨時呼叫它,我們將執行
- 只有當重置來自未知位置時,才需要呼叫此函式
由中間層本身發起的重置不需要呼叫此函式,但這樣做應該無害。
此函式的主要目的是確保正確處理 CHECK_CONDITION。
-
void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)¶
報告觀察到的裝置重置
引數
struct Scsi_Host *shost有問題的 Host
int channel觀察到重置的通道
int target觀察到重置的目標
描述
底層驅動程式使用的實用程式函式,用於報告它們已在正在處理的裝置上觀察到裝置重置。
鎖定狀態:必須持有主機鎖
返回
無
底層驅動程式可以隨時呼叫它,我們將執行
- 只有當重置來自未知位置時,才需要呼叫此函式
由中間層本身發起的重置不需要呼叫此函式,但這樣做應該無害。
此函式的主要目的是確保正確處理 CHECK_CONDITION。
-
bool scsi_get_sense_info_fld(const u8 *sense_buffer, int sb_len, u64 *info_out)¶
從 sense 資料(固定格式或描述符格式)獲取資訊欄位
引數
const u8 *sense_buffersense 資料的位元組陣列
int sb_lensense_buffer 中的有效位元組數
u64 *info_out指向 64 位整數的指標,如果找到 8 位元組或 4 位元組的資訊欄位,則將放置在此處。
描述
- 返回值
如果找到資訊欄位,則為 true;如果未找到,則為 false。
drivers/scsi/scsi_devinfo.c¶
管理 scsi_dev_info_list,它跟蹤黑名單和白名單裝置。
-
int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model, char *strflags, blist_flags_t flags, enum scsi_devinfo_key key)¶
新增一個 dev_info 列表條目。
引數
int compatible如果為 true,則以 null 結尾短字串。否則,使用空格填充。
char *vendor供應商字串
char *model型號(產品)字串
char *strflags整數字符串
blist_flags_t flags如果 strflags 為 NULL,則使用此標誌值
enum scsi_devinfo_key key指定要使用的列表
描述
為 vendor、model、strflags 或 flag 在 key 指定的列表中建立並新增一個 dev_info 條目。如果 compatible,則新增到列表的尾部,不使用空格填充,並設定 devinfo->compatible。 scsi_static_device_list 條目使用 compatible 1 和 clfags NULL 新增。
返回
0 OK,失敗時返回 -error。
-
blist_flags_t scsi_get_device_flags_keyed(struct scsi_device *sdev, const unsigned char *vendor, const unsigned char *model, enum scsi_devinfo_key key)¶
從動態裝置列表中獲取裝置特定標誌
引數
struct scsi_device *sdev要獲取標誌的
scsi_deviceconst unsigned char *vendor供應商名稱
const unsigned char *model型號名稱
enum scsi_devinfo_key key要查詢的列表
描述
搜尋 key 指定的 scsi_dev_info_list 中與 vendor 和 model 匹配的條目,如果找到,則返回匹配的標誌值,否則返回主機或全域性預設設定。 在掃描時呼叫。
-
int scsi_dev_info_add_list(enum scsi_devinfo_key key, const char *name)¶
新增新的 devinfo 列表
引數
enum scsi_devinfo_key key要新增的列表的鍵
const char *name要新增的列表的名稱(用於 /proc/scsi/device_info)
描述
新增請求的列表,成功時返回零,如果該鍵已註冊到列表,則返回 -EEXIST,否則返回其他錯誤。
-
int scsi_dev_info_remove_list(enum scsi_devinfo_key key)¶
銷燬新增的 devinfo 列表
引數
enum scsi_devinfo_key key要銷燬的列表的鍵
描述
首先迭代整個列表,釋放所有值,然後釋放列表本身。 成功時返回 0,如果找不到該鍵,則返回 -EINVAL。
drivers/scsi/scsi_ioctl.c¶
處理 SCSI 裝置的 ioctl() 呼叫。
-
int scsi_set_medium_removal(struct scsi_device *sdev, char state)¶
傳送命令以允許或阻止介質移除
引數
struct scsi_device *sdev目標 scsi 裝置
char state要設定的移除狀態(阻止或允許)
返回
如果 sdev 不可移動或不可鎖定或成功,則返回
0。如果 > 0,則非
0是 SCSI 結果程式碼;如果 < 0,則為核心錯誤程式碼。成功時,將 sdev->locked 設定為新狀態。
-
bool scsi_cmd_allowed(unsigned char *cmd, bool open_for_write)¶
檢查是否允許給定命令。
引數
unsigned char *cmd要檢查的 SCSI 命令
bool open_for_write是否為寫入開啟檔案/塊裝置?
描述
只有一部分命令允許非特權使用者使用。 用於格式化介質、更新韌體等的命令是不允許的。
返回
如果允許 cmd,則返回 true,否則返回 false。
-
int scsi_ioctl(struct scsi_device *sdev, bool open_for_write, int cmd, void __user *arg)¶
將 ioctl 分派到 scsi 裝置
引數
struct scsi_device *sdev接收 ioctl 的 scsi 裝置
bool open_for_write是否為寫入開啟檔案/塊裝置?
int cmd是哪個 ioctl
void __user *arg與 ioctl 相關的資料
描述
scsi_ioctl() 函式與大多數 ioctl 不同之處在於,它不採用主/次編號作為 dev 欄位。 而是,它採用指向 struct scsi_device 的指標。
返回
因 cmd 而異
-
int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd, bool ndelay)¶
防止命令排隊
引數
struct scsi_device *sdev目標 scsi 裝置
int cmd是哪個 ioctl
bool ndelay無延遲(非阻塞)
描述
即使裝置未完全執行,我們也可以處理重置。
返回
成功時返回 0,<0 表示錯誤程式碼。
drivers/scsi/scsi_lib.c¶
SCSI 佇列庫。
-
void scsi_failures_reset_retries(struct scsi_failures *failures)¶
將所有故障重置為零
引數
struct scsi_failures *failures設定了特定故障模式的
struct scsi_failures
-
int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd, blk_opf_t opf, void *buffer, unsigned int bufflen, int timeout, int ml_retries, const struct scsi_exec_args *args)¶
插入請求並等待結果
引數
struct scsi_device *sdevscsi_device
const unsigned char *cmdscsi 命令
blk_opf_t opf塊層請求 cmd_flags
void *buffer資料緩衝區
unsigned int bufflen緩衝區長度
int timeout以 HZ 為單位的請求超時
int ml_retriesSCSI 中間層將重試請求的次數
const struct scsi_exec_args *args可選引數。 有關欄位說明,請參閱結構定義
描述
如果執行了命令,則返回 scsi_cmnd 結果欄位;如果未執行命令,則返回負 Linux 錯誤程式碼。
-
blk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd)¶
分配和初始化資料和完整性散列表
引數
struct scsi_cmnd *cmd要初始化的 SCSI 命令資料結構。
描述
初始化 cmd->sdb,如果為 cmd 啟用了資料完整性,則還初始化 cmd->prot_sdb。
返回
BLK_STS_OK - 成功時
BLK_STS_RESOURCE - 如果故障可以重試
BLK_STS_IOERR - 如果故障是致命的
-
struct request *scsi_alloc_request(struct request_queue *q, blk_opf_t opf, blk_mq_req_flags_t flags)¶
分配塊請求並部分初始化其
scsi_cmnd
引數
struct request_queue *q裝置的請求佇列
blk_opf_t opf請求操作碼
blk_mq_req_flags_t flags塊層分配標誌
返回
成功時返回 struct request 指標,失敗時返回 NULL
-
struct scsi_device *scsi_device_from_queue(struct request_queue *q)¶
返回與 request_queue 關聯的 sdev
引數
struct request_queue *q要從中返回 sdev 的請求佇列
描述
返回與請求佇列關聯的 sdev,如果 request_queue 未引用 SCSI 裝置,則返回 NULL。
-
void scsi_block_requests(struct Scsi_Host *shost)¶
底層驅動程式使用的實用程式函式,用於防止將更多命令排隊到裝置。
-
void scsi_unblock_requests(struct Scsi_Host *shost)¶
底層驅動程式使用的實用函式,用於允許將更多命令排隊到裝置。
引數
struct Scsi_Host *shost相關主機
描述
除了底層驅動程式呼叫 scsi_unblock_requests() 之外,沒有任何計時器或其他方法可以解除對請求的阻止。 這樣做是為了作為一個 API 函式,以便對 SCSI 中間層內部的更改不會要求對使用此功能的驅動程式進行大規模更改。
-
int scsi_mode_select(struct scsi_device *sdev, int pf, int sp, unsigned char *buffer, int len, int timeout, int retries, struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr)¶
發出模式選擇
引數
struct scsi_device *sdev要查詢的 SCSI 裝置
int pf頁面格式位 (1 == 標準,0 == 廠商特定)
int sp儲存頁面位 (0 == 不儲存,1 == 儲存)
unsigned char *buffer請求緩衝區 (不得小於 8 個位元組)
int len請求緩衝區的長度。
int timeout命令超時
int retries失敗之前的重試次數
struct scsi_mode_data *data返回一個抽象模式頭資料的結構
struct scsi_sense_hdr *sshdr放置 sense 資料的空間 (如果不需要收集 sense 資料,則為 NULL)。必須是 SCSI_SENSE_BUFFERSIZE 大小。
如果成功則返回零;如果出錯,則返回負錯誤號或 SCSI 狀態
-
int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, int subpage, unsigned char *buffer, int len, int timeout, int retries, struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr)¶
發出模式感測,如有必要,從 10 位元組回退到 6 位元組。
引數
struct scsi_device *sdev要查詢的 SCSI 裝置
int dbd設定以防止模式感測返回塊描述符
int modepage正在請求的模式頁
int subpage正在請求的模式頁的子頁
unsigned char *buffer請求緩衝區 (不得小於 8 個位元組)
int len請求緩衝區的長度。
int timeout命令超時
int retries失敗之前的重試次數
struct scsi_mode_data *data返回一個抽象模式頭資料的結構
struct scsi_sense_hdr *sshdr放置 sense 資料的空間 (如果不需要收集 sense 資料,則為 NULL)。必須是 SCSI_SENSE_BUFFERSIZE 大小。
如果成功則返回零,如果失敗則返回負錯誤號
-
int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, struct scsi_sense_hdr *sshdr)¶
測試單元是否就緒
引數
struct scsi_device *sdev要更改狀態的 SCSI 裝置。
int timeout命令超時
int retries失敗之前的重試次數
struct scsi_sense_hdr *sshdr解碼後的 sense 資訊的輸出指標。
如果 TUR 失敗,則返回零表示不成功,否則返回錯誤。 對於可移動介質,UNIT_ATTENTION 設定 ->changed 標誌。
-
int scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)¶
使給定的裝置透過裝置狀態模型。
引數
struct scsi_device *sdev要更改狀態的 SCSI 裝置。
enum scsi_device_state state要更改為的狀態。
如果成功則返回零,如果請求的轉換是非法的則返回錯誤。
-
void sdev_evt_send(struct scsi_device *sdev, struct scsi_event *evt)¶
將斷言的事件傳送到 uevent 執行緒
引數
struct scsi_device *sdevscsi_device 上發生的事件
struct scsi_event *evt要傳送的事件
非同步斷言 SCSI 裝置事件。
-
struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, gfp_t gfpflags)¶
分配一個新的 SCSI 事件
引數
enum scsi_device_event evt_type要分配的事件型別
gfp_t gfpflags用於分配的 GFP 標誌
分配並返回一個新的 scsi_event。
-
void sdev_evt_send_simple(struct scsi_device *sdev, enum scsi_device_event evt_type, gfp_t gfpflags)¶
將斷言的事件傳送到 uevent 執行緒
引數
struct scsi_device *sdevscsi_device 上發生的事件
enum scsi_device_event evt_type要傳送的事件型別
gfp_t gfpflags用於分配的 GFP 標誌
非同步斷言 SCSI 裝置事件,給定事件型別。
-
int scsi_device_quiesce(struct scsi_device *sdev)¶
阻止除電源管理之外的所有命令。
引數
struct scsi_device *sdev要暫停的 SCSI 裝置。
這透過嘗試轉換到 SDEV_QUIESCE 狀態 (必須是合法的轉換) 來實現。 當裝置處於此狀態時,只會接受電源管理請求,所有其他請求將被延遲。
必須使用使用者上下文呼叫,可能會休眠。
如果成功則返回零,如果失敗則返回錯誤。
-
void scsi_device_resume(struct scsi_device *sdev)¶
重新啟動已暫停裝置的使用者發出的命令。
引數
struct scsi_device *sdev要恢復的 SCSI 裝置。
將裝置從暫停狀態移動回執行狀態並重新啟動佇列。
必須使用使用者上下文呼叫,可能會休眠。
-
int scsi_internal_device_block_nowait(struct scsi_device *sdev)¶
嘗試轉換到 SDEV_BLOCK 狀態
引數
struct scsi_device *sdev要阻止的裝置
描述
暫停指定裝置上的 SCSI 命令處理。 不會休眠。
如果成功則返回零,如果失敗則返回負錯誤程式碼。
底層驅動程式可以隨時呼叫它,我們將執行
此例程將裝置轉換到 SDEV_BLOCK 狀態 (必須是合法的轉換)。 當裝置處於此狀態時,命令處理將被暫停,直到裝置離開 SDEV_BLOCK 狀態。 另請參閱 scsi_internal_device_unblock_nowait()。
-
int scsi_internal_device_unblock_nowait(struct scsi_device *sdev, enum scsi_device_state new_state)¶
在阻止請求後恢復裝置
引數
struct scsi_device *sdev要恢復的裝置
enum scsi_device_state new_state取消阻止後要將裝置設定為的狀態
描述
重新啟動先前暫停的 SCSI 裝置的裝置佇列。 不會休眠。
如果成功則返回零,如果失敗則返回負錯誤程式碼。
底層驅動程式可以隨時呼叫它,我們將執行
此例程將裝置轉換到 SDEV_RUNNING 狀態或其中一個離線狀態 (必須是合法的轉換),允許中間層推動此裝置的佇列。
引數
struct Scsi_Host *shost此裝置所屬的 Scsi_Host
struct device *dev一個或多個 scsi_target 裝置的父裝置
描述
迭代 **dev** 的所有子裝置,這些子裝置應該是 scsi_target 裝置,並將所有下級 SCSI 裝置切換到 SDEV_BLOCK 狀態。 等待正在進行的 scsi_queue_rq() 呼叫完成。 可能會休眠。
注意
**dev** 本身不得是 scsi_target 裝置。
-
int scsi_host_block(struct Scsi_Host *shost)¶
嘗試將所有邏輯單元轉換到 SDEV_BLOCK 狀態
引數
struct Scsi_Host *shost要阻止的裝置
描述
暫停與 SCSI 主機關聯的所有邏輯單元的 SCSI 命令處理,並等待掛起的 scsi_queue_rq() 呼叫完成。
如果成功則返回零,如果失敗則返回負錯誤程式碼。
-
void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count, size_t *offset, size_t *len)¶
查詢並原子地對映一個 sg 元素
引數
struct scatterlist *sgl分散-聚集列表
int sg_countsg 中的段數
size_t *offsetsg 中的位元組偏移量,返回時為對映區域中的偏移量
size_t *len要對映的位元組數,返回時為對映的位元組數
描述
返回對映頁面開始的虛擬地址
-
void scsi_kunmap_atomic_sg(void *virt)¶
原子地取消對映一個虛擬地址,該地址先前已使用 scsi_kmap_atomic_sg 對映
引數
void *virt要取消對映的虛擬地址
-
int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len)¶
返回唯一的裝置標識
引數
struct scsi_device *sdevSCSI 裝置
char *id標識的緩衝區
size_t id_len緩衝區的長度
描述
基於裝置 VPD 頁面 0x83 中的資訊,將唯一的裝置標識複製到 **id** 中。 該字串將格式化為 SCSI 名稱字串。
如果成功,則返回標識的長度,如果失敗,則返回錯誤。 如果識別符號長於提供的緩衝區,則返回實際的識別符號長度,並且緩衝區不會被零填充。
-
int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id)¶
返回目標埠組識別符號
引數
struct scsi_device *sdevSCSI 裝置
int *rel_id指向返回相對目標埠的指標 (如果不是
NULL)
描述
從裝置的 VPD 頁面 0x83 中的資訊返回目標埠組識別符號。 (可選)成功時將 **rel_id** 設定為相對目標埠。
返回
識別符號,如果失敗,則返回錯誤。
-
void scsi_build_sense(struct scsi_cmnd *scmd, int desc, u8 key, u8 asc, u8 ascq)¶
為命令構建 sense 資料
引數
struct scsi_cmnd *scmd應為其格式化 sense 資料的 scsi 命令
int descSense 格式(非零 == 描述符格式, 0 == 固定格式)
u8 keySense 鍵
u8 asc附加 sense 程式碼
u8 ascq附加 sense 程式碼限定符
drivers/scsi/scsi_lib_dma.c¶
依賴於 DMA 的 SCSI 庫函式 (對映和取消對映 scatter-gather 列表).
-
int scsi_dma_map(struct scsi_cmnd *cmd)¶
針對命令的 sg 列表執行 DMA 對映
引數
struct scsi_cmnd *cmdscsi 命令
描述
返回實際使用的 sg 列表數量,如果 sg 列表為 NULL 則返回 0,如果對映失敗則返回 -ENOMEM。
-
void scsi_dma_unmap(struct scsi_cmnd *cmd)¶
取消對映 scsi_dma_map 對映的命令 sg 列表
引數
struct scsi_cmnd *cmdscsi 命令
drivers/scsi/scsi_proc.c¶
此檔案中的函式提供 PROC 檔案系統和 SCSI 裝置驅動程式之間的介面。它主要用於除錯、統計以及將資訊直接傳遞到低階驅動程式。例如,用於管理 /proc/scsi/*
-
struct scsi_proc_entry¶
(主機模板,SCSI proc 目錄) 關聯
定義:
struct scsi_proc_entry {
struct list_head entry;
const struct scsi_host_template *sht;
struct proc_dir_entry *proc_dir;
unsigned int present;
};
成員
條目scsi_proc_list 中的條目。
sht與 procfs 目錄關聯的 SCSI 主機模板。
proc_dir與 SCSI 主機模板關聯的 procfs 目錄。
present為 sht 例項化的 SCSI 主機的數量。
-
struct proc_dir_entry *scsi_template_proc_dir(const struct scsi_host_template *sht)¶
返回 SCSI 主機模板的 procfs 目錄
引數
const struct scsi_host_template *shtSCSI 主機模板指標。
-
int scsi_proc_hostdir_add(const struct scsi_host_template *sht)¶
在 /proc 中為 scsi 主機建立目錄
引數
const struct scsi_host_template *sht此目錄的所有者
描述
將 sht->proc_dir 設定為新目錄。
-
void scsi_proc_hostdir_rm(const struct scsi_host_template *sht)¶
刪除 /proc 中 scsi 主機的目錄
引數
const struct scsi_host_template *sht目錄的所有者
-
void scsi_proc_host_add(struct Scsi_Host *shost)¶
將此主機的條目新增到相應的 /proc 目錄
引數
struct Scsi_Host *shost要新增的主機
-
void scsi_proc_host_rm(struct Scsi_Host *shost)¶
從 /proc 中刪除此主機的條目
引數
struct Scsi_Host *shost哪個主機
引數
struct device *dev一個 scsi 裝置
void *data要輸出到的
struct seq_file。
描述
列印主機、通道、Id、Lun、供應商、型號、版本、型別和修訂。
-
int scsi_add_single_device(uint host, uint channel, uint id, uint lun)¶
響應使用者探測/新增裝置請求
引數
uint host使用者提供的十進位制整數
uint channel使用者提供的十進位制整數
uint id使用者提供的十進位制整數
uint lun使用者提供的十進位制整數
描述
透過寫入“scsi add-single-device”到 /proc/scsi/scsi 來呼叫。
執行 scsi_host_lookup(),如果該傳輸型別支援,則執行 user_scan(),否則執行 scsi_scan_host_selected()
注意
這似乎專門針對 SCSI 並行匯流排。
-
int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)¶
響應使用者刪除裝置請求
引數
uint host使用者提供的十進位制整數
uint channel使用者提供的十進位制整數
uint id使用者提供的十進位制整數
uint lun使用者提供的十進位制整數
描述
透過寫入“scsi remove-single-device”到 /proc/scsi/scsi 來呼叫。執行 scsi_device_lookup() 和 scsi_remove_device()
-
ssize_t proc_scsi_write(struct file *file, const char __user *buf, size_t length, loff_t *ppos)¶
處理寫入 /proc/scsi/scsi 的操作
引數
struct file *file未使用
const char __user *buf要寫入的緩衝區
size_t lengthbuf 的長度,最多 PAGE_SIZE
loff_t *ppos未使用
描述
這提供了一種傳統機制,用於按主機、通道、ID 和 Lun 新增或刪除裝置。要使用,請執行“echo ‘scsi add-single-device 0 1 2 3’ > /proc/scsi/scsi”或“echo ‘scsi remove-single-device 0 1 2 3’ > /proc/scsi/scsi”,其中“0 1 2 3”替換為主機、通道、Id 和 Lun。
注意
這似乎針對並行 SCSI。大多數現代匯流排(USB、SATA、Firewire、光纖通道等)動態分配這些值,以提供一個唯一識別符號,僅此而已。
引數
struct inode *inode未使用
struct file *file傳遞給 single_open()
描述
將 proc_scsi_show 與此檔案關聯
-
int scsi_init_procfs(void)¶
在 procfs 中建立 scsi 和 scsi/scsi
引數
void無引數
-
void scsi_exit_procfs(void)¶
從 procfs 中刪除 scsi/scsi 和 scsi
引數
void無引數
drivers/scsi/scsi_netlink.c¶
基礎設施,用於透過 netlink 將傳輸的非同步事件提供給使用者空間,為所有傳輸使用單個 NETLINK_SCSITRANSPORT 協議。有關更多詳細資訊,請參閱 原始補丁提交。
引數
struct sk_buff *skb套接字接收緩衝區
描述
- 從接收緩衝區提取訊息。
驗證訊息頭並呼叫相應的傳輸訊息處理程式
-
void scsi_netlink_init(void)¶
由 SCSI 子系統呼叫,以初始化 SCSI 傳輸 netlink 介面
引數
void無引數
-
void scsi_netlink_exit(void)¶
由 SCSI 子系統呼叫,以停用 SCSI 傳輸 netlink 介面
引數
void無引數
drivers/scsi/scsi_scan.c¶
掃描主機以確定連線了哪些(如果有)裝置。一般的掃描/探測演算法如下,根據裝置特定標誌、編譯選項和全域性變數(啟動或模組載入時間)設定對其進行例外處理。透過 INQUIRY 命令掃描特定 LUN;如果 LUN 連線了裝置,則會為此分配並設定一個 scsi_device。對於給定主機上每個通道的每個 id,首先掃描 LUN 0。跳過根本不響應 LUN 0 掃描的主機。否則,如果 LUN 0 連線了裝置,則為其分配並設定一個 scsi_device。如果目標是 SCSI-3 或更高版本,則發出 REPORT LUN,並掃描 REPORT LUN 返回的所有 LUN;否則,按順序掃描 LUN,直到達到某個最大值,或者看到一個無法連線裝置的 LUN。
-
void scsi_sanitize_inquiry_string(unsigned char *s, int len)¶
從 INQUIRY 結果字串中刪除非圖形字元
引數
unsigned char *s要清理的 INQUIRY 結果字串
int len字串的長度
描述
SCSI 規範規定,INQUIRY 供應商、產品和版本字串必須完全由圖形 ASCII 字元組成,並在右側用空格填充。由於並非所有裝置都遵守此規則,因此我們將用空格替換非圖形或非 ASCII 字元。例外:NUL 字元被解釋為字串終止符,因此所有後續字元都設定為空格。
-
int scsi_add_device(struct Scsi_Host *host, uint channel, uint target, u64 lun)¶
建立新的 SCSI (LU) 例項
引數
struct Scsi_Host *host裝置所在的
Scsi_Host例項uint channel目標通道號(很少不是
0)uint target目標 id 號
u64 lun目標裝置的 LUN
描述
探測特定 LUN 並在找到時新增它。
底層驅動程式可以隨時呼叫它,我們將執行
此呼叫通常在新增 HBA 時在 SCSI 匯流排掃描期間在內部執行(即 scsi_scan_host())。因此,只有在 HBA 在 scsi_scan_host() 完成後意識到新的 SCSI 裝置 (LU) 時,才應呼叫它。如果成功,此呼叫可能會導致 sdev_init() 和 sdev_configure() 回撥到 LLD。
返回
成功時返回 0,失敗時返回負錯誤程式碼
-
void scsi_scan_target(struct device *parent, unsigned int channel, unsigned int id, u64 lun, enum scsi_scan_mode rescan)¶
掃描目標 id,可能包括目標上的所有 LUN。
引數
struct device *parent要掃描的主機
unsigned int channel要掃描的通道
unsigned int id要掃描的目標 ID
u64 lun要掃描的特定 LUN,或 SCAN_WILD_CARD
enum scsi_scan_mode rescan傳遞給 LUN 掃描例程;SCSI_SCAN_INITIAL 表示不重新掃描,SCSI_SCAN_RESCAN 表示重新掃描現有 LUN,SCSI_SCAN_MANUAL 表示強制掃描,即使設定了“scan=manual”。
描述
掃描 **parent**、**channel** 和 **id** 上的目標 ID。至少掃描 LUN 0,可能掃描目標 ID 上的所有 LUN。
首先嚐試 REPORT LUN 掃描,如果這樣無法掃描目標,則對目標 ID 上的 LUN 進行順序掃描。
-
void scsi_scan_host(struct Scsi_Host *shost)¶
掃描給定的介面卡
引數
struct Scsi_Host *shost要掃描的介面卡
底層驅動程式可以隨時呼叫它,我們將執行
應在 scsi_add_host() 之後呼叫
drivers/scsi/scsi_sysctl.c¶
設定 sysctl 條目:“/dev/scsi/logging_level”(DEV_SCSI_LOGGING_LEVEL),用於設定/返回 scsi_logging_level。
drivers/scsi/scsi_sysfs.c¶
SCSI sysfs 介面例程。
-
void scsi_remove_device(struct scsi_device *sdev)¶
從 SCSI 總線上登出裝置
引數
struct scsi_device *sdev要登出的 scsi_device
引數
struct device *dev要刪除的通用 starget 或通用 starget 的父級
注意
這有點競爭。如果使用者請求新增另一個裝置,則可能無法刪除目標。
drivers/scsi/hosts.c¶
中間層到低層 SCSI 驅動程式介面
-
void scsi_remove_host(struct Scsi_Host *shost)¶
刪除 SCSI 主機
引數
struct Scsi_Host *shost要刪除的 SCSI 主機的指標
-
int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, struct device *dma_dev)¶
新增帶有 DMA 裝置的 SCSI 主機
引數
struct Scsi_Host *shost要新增的 SCSI 主機指標
struct device *devscsi 類型別的
struct devicestruct device *dma_dev主機的 DMA 裝置
注意
除非您處於虛擬化主機環境中,否則您很少需要擔心這一點,因此請使用更簡單的 scsi_add_host() 函式。
描述
- 返回值
成功時為 0 / 錯誤時為 != 0
-
struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int privsize)¶
註冊 SCSI 主機介面卡例項。
引數
const struct scsi_host_template *shtSCSI 主機模板的指標
int privsize為驅動程式分配的額外位元組
注意
分配新的 Scsi_Host 並執行基本初始化。在呼叫 scsi_add_host 之前,不會將主機發布到 SCSI 中間層。
描述
- 返回值
指向新的 Scsi_Host 的指標
-
struct Scsi_Host *scsi_host_lookup(unsigned int hostnum)¶
按主機號獲取對 Scsi_Host 的引用
引數
unsigned int hostnum要查詢的主機號
描述
- 返回值
指向已定位的 Scsi_Host 的指標,如果找不到則為 NULL。
呼叫者必須執行
scsi_host_put()以刪除scsi_host_get()採用的引用。下面的put_device()刪除了來自class_find_device()的引用。
-
struct Scsi_Host *scsi_host_get(struct Scsi_Host *shost)¶
增加 Scsi_Host 引用計數
引數
struct Scsi_Host *shost指向要增加的 Scsi_Host 的指標。
-
int scsi_host_busy(struct Scsi_Host *shost)¶
返回主機忙碌計數器
引數
struct Scsi_Host *shost指向要增加的 Scsi_Host 的指標。
-
void scsi_host_put(struct Scsi_Host *shost)¶
減少 Scsi_Host 引用計數
引數
struct Scsi_Host *shost指向要減少的 Scsi_Host 的指標。
-
int scsi_queue_work(struct Scsi_Host *shost, struct work_struct *work)¶
將工作排隊到 Scsi_Host 工作佇列。
引數
struct Scsi_Host *shost指向 Scsi_Host 的指標。
struct work_struct *work要排隊執行的工作。
描述
- 返回值
1 - 工作已排隊等待執行 0 - 工作已排隊 -EINVAL - 工作佇列不存在
-
void scsi_flush_work(struct Scsi_Host *shost)¶
重新整理 Scsi_Host 的工作佇列。
引數
struct Scsi_Host *shost指向 Scsi_Host 的指標。
-
void scsi_host_complete_all_commands(struct Scsi_Host *shost, enum scsi_host_status status)¶
終止所有正在執行的命令
引數
struct Scsi_Host *shost應終止命令的 SCSI 主機
enum scsi_host_status status為終止的命令設定的狀態
描述
沒有針對修改未完成命令數的保護。呼叫者有責任確保在呼叫此函式時停止併發 I/O 提交和/或完成。
-
void scsi_host_busy_iter(struct Scsi_Host *shost, bool (*fn)(struct scsi_cmnd*, void*), void *priv)¶
迭代所有忙碌命令
引數
struct Scsi_Host *shost指向 Scsi_Host 的指標。
bool (*fn)(struct scsi_cmnd *, void *)在每個忙碌命令上呼叫的函式
void *priv傳遞給 **fn** 的資料指標
描述
如果需要鎖定以防止併發命令完成,則必須由呼叫者提供
drivers/scsi/scsi_common.c¶
通用支援函式
-
const char *scsi_device_type(unsigned type)¶
返回指示裝置型別的 17 字元字串。
引數
unsigned type要查詢的型別編號
-
u64 scsilun_to_int(struct scsi_lun *scsilun)¶
將 scsi_lun 轉換為 int
引數
struct scsi_lun *scsilun要轉換的 struct scsi_lun。
描述
將 **scsilun** 從 struct scsi_lun 轉換為四位元組的主機位元組序整數,並返回結果。呼叫者在使用此函式之前必須檢查截斷。
底層驅動程式可以隨時呼叫它,我們將執行
有關 LUN 格式的描述,請參閱 SCSI-3 後的 SCSI 架構模型,有關 SCSI-3 請參閱 SCSI 控制器命令。
給定一個 struct scsi_lun:d2 04 0b 03 00 00 00 00,此函式返回整數:0x0b03d204
對於小於 256 的 LUN,此編碼將返回標準整數 LUN,通常使用定址方法 0 的單級 LUN 結構。
-
void int_to_scsilun(u64 lun, struct scsi_lun *scsilun)¶
將 int 恢復為 scsi_lun
引數
u64 lun要恢復的整數
struct scsi_lun *scsilun要設定的 struct scsi_lun。
描述
恢復 scsilun_to_int 的功能,它將 8 位元組的 LUN 值打包到 int 中。此例程將 int 解包回 LUN 值。
底層驅動程式可以隨時呼叫它,我們將執行
給定一個整數:0x0b03d204,此函式返回一個 struct scsi_lun:d2 04 0b 03 00 00 00 00
-
bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, struct scsi_sense_hdr *sshdr)¶
將固定或描述符錯誤資料格式中的主要元素規範化為通用格式。
引數
const u8 *sense_buffer包含裝置返回的錯誤資料的位元組陣列
int sb_lensense_buffer 中的有效位元組數
struct scsi_sense_hdr *sshdr指向將寫入公共元素的結構例項的指標。
底層驅動程式可以隨時呼叫它,我們將執行
來自錯誤資料的“主要元素”是:response_code、sense_key、asc、ascq 和 additional_length(僅適用於描述符格式)。
通常,可以在裝置使用 CHECK_CONDITION 狀態響應 SCSI 命令後呼叫此函式。
描述
- 返回值
如果找到有效的錯誤資料資訊,則為 true,否則為 false;
-
const u8 *scsi_sense_desc_find(const u8 *sense_buffer, int sb_len, int desc_type)¶
在描述符錯誤資料格式中搜索給定的描述符型別。
引數
const u8 * sense_buffer描述符格式錯誤資料的位元組陣列
int sb_lensense_buffer 中的有效位元組數
int desc_type要查詢的描述符型別的值(例如,0 -> 資訊)
底層驅動程式可以隨時呼叫它,我們將執行
僅當錯誤資料採用描述符格式時才有效
描述
- 返回值
指向找到的(第一個)描述符的開始位置的指標,否則為 NULL
-
void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq)¶
在緩衝區中構建錯誤資料
引數
int descSense 格式(非零 == 描述符格式, 0 == 固定格式)
u8 *buf在何處構建錯誤資料
u8 keySense 鍵
u8 asc附加 sense 程式碼
u8 ascq附加 sense 程式碼限定符
-
int scsi_set_sense_information(u8 *buf, int buf_len, u64 info)¶
在格式化的錯誤資料緩衝區中設定資訊欄位
引數
u8 *buf在何處構建錯誤資料
int buf_len緩衝區長度
u64 info要設定的 64 位資訊值
描述
- 返回值
成功時為 0,無效錯誤緩衝區長度時為 -EINVAL
-
int scsi_set_sense_field_pointer(u8 *buf, int buf_len, u16 fp, u8 bp, bool cd)¶
在格式化的 sense 資料緩衝區中設定欄位指標 sense key 特定資訊
引數
u8 *buf在何處構建錯誤資料
int buf_len緩衝區長度
u16 fp要設定的欄位指標
u8 bp要設定的位指標
bool cd命令/資料位
描述
- 返回值
成功時為 0,無效錯誤緩衝區長度時為 -EINVAL
傳輸類¶
傳輸類是 SCSI 下層驅動程式的 service 庫,可在 sysfs 中公開傳輸屬性。
光纖通道傳輸¶
檔案 drivers/scsi/scsi_transport_fc.c 定義了光纖通道的傳輸屬性。
-
u32 fc_get_event_number(void)¶
獲取下一個連續的 FC 事件編號
引數
void無引數
底層驅動程式可以隨時呼叫它,我們將執行
我們可以內聯這個,但這需要公開 fc_event_seq。目前,暫時使用子例程呼叫。使用 Atomic 避免鎖定/解鎖...
-
void fc_host_post_fc_event(struct Scsi_Host *shost, u32 event_number, enum fc_host_event_code event_code, u32 data_len, char *data_buf, u64 vendor_id)¶
在 fc_host 上釋出事件的例程。
引數
struct Scsi_Host *shost事件發生的主機
u32 event_number從 get_fc_event_number() 獲取的 fc 事件編號
enum fc_host_event_code event_code正在釋出的 fc_host 事件
u32 data_len事件資料量,以位元組為單位
char *data_buf指向事件資料的指標
u64 vendor_id供應商 ID 的值
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
void fc_host_post_event(struct Scsi_Host *shost, u32 event_number, enum fc_host_event_code event_code, u32 event_data)¶
呼叫以在 fc_host 上釋出 even。
引數
struct Scsi_Host *shost事件發生的主機
u32 event_number從 get_fc_event_number() 獲取的 fc 事件編號
enum fc_host_event_code event_code正在釋出的 fc_host 事件
u32 event_data正在釋出的事件的 32 位資料
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, u32 data_len, char *data_buf, u64 vendor_id)¶
呼叫以在 fc_host 上釋出廠商唯一事件
引數
struct Scsi_Host *shost事件發生的主機
u32 event_number從 get_fc_event_number() 獲取的 fc 事件編號
u32 data_len廠商唯一資料的數量,以位元組為單位
char * data_buf指向廠商唯一資料的指標
u64 vendor_id廠商 ID
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
struct fc_rport *fc_find_rport_by_wwpn(struct Scsi_Host *shost, u64 wwpn)¶
查詢給定 wwpn 的 fc_rport 指標
引數
struct Scsi_Host *shostfc_rport 相關聯的主機
u64 wwpnfc_rport 裝置的 wwpn
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
void fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf, u8 event_acknowledge)¶
處理收到的 FPIN 的例程。
引數
struct Scsi_Host *shost收到 FPIN 的主機
u32 fpin_lenFPIN 有效負載的長度,以位元組為單位
char *fpin_buf指向 FPIN 有效負載的指標
u8 event_acknowledge如果 LLDD 處理此事件,則為 1。
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
enum scsi_timeout_action fc_eh_timed_out(struct scsi_cmnd *scmd)¶
FC 傳輸 I/O 超時攔截處理程式
引數
struct scsi_cmnd *scmd超時的 SCSI 命令
描述
此例程可以防止在 rport 處於阻止狀態時呼叫錯誤處理程式,通常是由於暫時失去連線。 如果允許錯誤處理程式繼續,則中止 i/o、重置目標等請求很可能會失敗,因為無法與裝置通訊以執行所請求的功能。 這些故障可能導致中間層使裝置離線,需要手動干預才能恢復操作。
此例程在 i/o 超時時呼叫,用於驗證底層 rport 的狀態。 如果 rport 被阻止,它將返回 EH_RESET_TIMER,這將繼續重新安排超時。 最終,裝置將返回,或者 devloss_tmo 將觸發,並且當超時觸發時,它將被正常處理。 如果 rport 未被阻止,則繼續正常錯誤處理。
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
void fc_remove_host(struct Scsi_Host *shost)¶
呼叫以終止 scsi 主機的任何 fc_transport 相關元素。
引數
struct Scsi_Host *shost哪個
Scsi_Host
描述
預計此例程將在驅動程式呼叫 scsi_remove_host() 之前立即呼叫。
- 警告:使用 fc_transport 的驅動程式,如果未能呼叫
在
scsi_remove_host()之前執行此例程,將會在 /sys/class/fc_remote_ports 中留下懸掛物件。 訪問任何這些物件都可能導致系統崩潰!!!
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost, int channel, struct fc_rport_identifiers *ids)¶
通知 fc 傳輸遠端 FC 埠的存在。
引數
struct Scsi_Host *shost遠端埠連線到的 scsi 主機。
int channel連線到的 shost 埠上的通道。
struct fc_rport_identifiers *ids遠端埠的全球通用名稱、fc 地址和 FC4 埠角色。
描述
LLDD 呼叫此例程以通知傳輸遠端埠的存在。 LLDD 提供埠的唯一識別符號(wwpn、wwn)、其 FC 地址 (port_id) 以及埠的活動 FC4 角色。
對於作為 FCP 目標(又稱 scsi 目標)的埠,FC 傳輸代表 LLDD 維護一致的目標 ID 繫結。 一致的目標 ID 繫結是將目標 ID 分配給遠端埠識別符號,只要 scsi 主機已連線,該繫結就會持續存在。 遠端埠可以消失,然後稍後重新出現,其目標 ID 分配保持不變。 這允許 FC 定址的轉變(如果透過 wwpn 或 wwnn 繫結),而 scsi 子系統沒有任何明顯的變化,scsi 子系統基於 scsi 主機編號和目標 ID 值。 繫結僅在 scsi 主機連線期間有效。 如果主機分離,然後稍後重新連線,則目標 ID 繫結可能會更改。
此例程負責返回遠端埠結構。 此例程將搜尋代表一致目標 ID 對映在內部維護的遠端埠列表。 如果找到,則將重用遠端埠結構。 否則,將分配一個新的遠端埠結構。
每當分配遠端埠時,都會建立一個新的 fc_remote_port 類裝置。
不應從中斷上下文呼叫。
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
void fc_remote_port_delete(struct fc_rport *rport)¶
通知 fc 傳輸遠端埠不再存在。
引數
struct fc_rport *rport不再存在的遠端埠
描述
LLDD 呼叫此例程以通知傳輸遠端埠不再是拓撲的一部分。 注意:雖然埠可能不再是拓撲的一部分,但它可能仍然存在於 fc_host 顯示的遠端埠中。 我們在 2 種情況下執行此操作
如果埠是 scsi 目標,我們會透過“阻止”它來延遲其刪除。 這允許埠暫時消失,然後重新出現,而不會中斷連線到它的 SCSI 裝置樹。 在“阻止”期間,埠仍將存在。
如果埠是 scsi 目標並且消失的時間超過我們的預期,我們將刪除該埠並拆除連線到它的 SCSI 裝置樹。 但是,我們希望在最終存在的情況下半持久分配給該埠的目標 ID。 埠結構將保留(儘管資訊最少),以便目標 ID 繫結也保留。
如果遠端埠不是 FCP 目標,它將被完全拆除和釋放,包括 fc_remote_port 類裝置。
如果遠端埠是 FCP 目標,該埠將被置於臨時阻止狀態。 從 LLDD 的角度來看,rport 不再存在。 從 SCSI 中間層的角度來看,SCSI 目標存在,但它上面的所有 sdev 都被阻止進行進一步的 I/O。 然後預期以下情況。
如果遠端埠未在 dev_loss_tmo 超時內返回(透過 LLDD 呼叫
fc_remote_port_add()發出訊號),則刪除 scsi 目標 - 終止所有未完成的 i/o 並刪除連線到它的 scsi 裝置。 埠結構將被標記為不存在並被部分清除,僅留下足夠的資訊來識別相對於 scsi 目標 ID 繫結的遠端埠(如果它稍後出現)。 只要存在有效的繫結(例如,直到使用者更改繫結型別或解除安裝帶有繫結的 scsi 主機),埠將保持原樣。如果遠端埠在 dev_loss_tmo 值內返回(並根據目標 ID 繫結型別匹配),則將重用埠結構。 如果它不再是 SCSI 目標,則目標將被拆除。 如果它繼續是 SCSI 目標,則目標將被解除阻止(允許恢復 i/o),並且將啟用掃描以確保檢測到所有 lun。
僅從正常程序上下文呼叫 - 不能從中斷呼叫。
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)¶
通知 fc 傳輸遠端埠上的角色可能已更改。
引數
struct fc_rport *rport已更改的遠端埠。
u32 roles此埠的新角色。
描述
LLDD 呼叫此例程以通知傳輸遠端埠上的角色可能已更改。 最大的影響是,如果埠現在變為 FCP 目標,則必須為其分配 scsi 目標 ID。 如果埠不再是 FCP 目標,則分配給它的任何 scsi 目標 ID 值都將保留,以防角色更改回包括 FCP 目標。 如果角色發生變化(期望角色將被恢復),則不會呼叫 scsi 中間層的任何更改。 如果不這樣做,將進行正常的錯誤處理。
不應從中斷上下文呼叫。
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
int fc_block_rport(struct fc_rport *rport)¶
阻止用於阻止的 fc_rport 的 SCSI eh 執行緒。
引數
struct fc_rport *rportscsi_eh 嘗試恢復的遠端埠。
描述
可以從 FC LLD scsi_eh 回撥呼叫此例程。 它會阻止 scsi_eh 執行緒,直到 fc_rport 離開 FC_PORTSTATE_BLOCKED 狀態或觸發 fast_io_fail_tmo。 這對於避免 scsi_eh 無法執行阻止的 rport 的恢復操作是必要的,這會導致 SCSI 裝置離線。
返回
- 如果 fc_rport 離開 FC_PORTSTATE_BLOCKED 狀態,則為 0。
如果觸發了 fast_io_fail_tmo,則為 FAST_IO_FAIL,應將其傳遞迴 scsi_eh。
-
int fc_block_scsi_eh(struct scsi_cmnd *cmnd)¶
阻止用於阻止的 fc_rport 的 SCSI eh 執行緒
引數
struct scsi_cmnd *cmndscsi_eh 嘗試恢復的 SCSI 命令
描述
可以從 FC LLD scsi_eh 回撥呼叫此例程。 它會阻止 scsi_eh 執行緒,直到 fc_rport 離開 FC_PORTSTATE_BLOCKED 狀態或觸發 fast_io_fail_tmo。 這對於避免 scsi_eh 無法執行阻止的 rport 的恢復操作是必要的,這會導致 SCSI 裝置離線。
返回
- 如果 fc_rport 離開 FC_PORTSTATE_BLOCKED 狀態,則為 0。
如果觸發了 fast_io_fail_tmo,則為 FAST_IO_FAIL,應將其傳遞迴 scsi_eh。
-
struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel, struct fc_vport_identifiers *ids)¶
管理應用程式或 LLDD 請求建立 vport
引數
struct Scsi_Host *shost虛擬埠連線到的 scsi 主機。
int channel連線到的 shost 埠上的通道。
struct fc_vport_identifiers *ids虛擬埠的全球通用名稱、FC4 埠角色等。
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
-
int fc_vport_terminate(struct fc_vport *vport)¶
管理應用程式或 LLDD 請求終止 vport
引數
struct fc_vport *vport要終止的 fc_vport
描述
呼叫 LLDD vport_delete() 函式,然後從 shost 和物件樹中釋放並刪除 vport。
底層驅動程式可以隨時呼叫它,我們將執行
此例程假定入口處沒有持有鎖。
iSCSI 傳輸類¶
檔案 drivers/scsi/scsi_transport_iscsi.c 定義了 iSCSI 類的傳輸屬性,該類透過 TCP/IP 連線傳送 SCSI 資料包。
-
struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)¶
從控制代碼獲取 ep
引數
u64 handle端點控制代碼
描述
呼叫方必須執行 iscsi_put_endpoint。
-
struct iscsi_bus_flash_session *iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index, struct iscsi_transport *transport, int dd_size)¶
在sysfs中新增 flashnode 會話條目
引數
struct Scsi_Host *shost指向主機資料的指標
int index要在sysfs中新增的 flashnode 的索引
struct iscsi_transport *transport指向傳輸資料的指標
int dd_size要分配的總大小
描述
為 flashnode 會話屬性新增 sysfs 條目
返回
成功時指向已分配的 flashnode 會話的指標,失敗時為
NULL
-
struct iscsi_bus_flash_conn *iscsi_create_flashnode_conn(struct Scsi_Host *shost, struct iscsi_bus_flash_session *fnode_sess, struct iscsi_transport *transport, int dd_size)¶
在sysfs中新增 flashnode 連線條目
引數
struct Scsi_Host *shost指向主機資料的指標
struct iscsi_bus_flash_session *fnode_sess指向父 flashnode 會話條目的指標
struct iscsi_transport *transport指向傳輸資料的指標
int dd_size要分配的總大小
描述
為 flashnode 連線屬性新增 sysfs 條目
返回
成功時指向已分配的 flashnode 連線的指標,失敗時為
NULL
-
struct device *iscsi_find_flashnode_sess(struct Scsi_Host *shost, const void *data, device_match_t fn)¶
查詢 flashnode 會話條目
引數
struct Scsi_Host *shost指向主機資料的指標
const void *data指向包含用於比較的值的資料的指標
device_match_t fn執行實際比較的函式指標
描述
查詢 flashnode 會話物件,使用傳入的函式指標中定義的邏輯比較傳遞的資料
返回
成功時指向找到的 flashnode 會話裝置物件的指標,失敗時為
NULL
-
struct device *iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess)¶
查詢 flashnode 連線條目
引數
struct iscsi_bus_flash_session *fnode_sess指向父 flashnode 會話條目的指標
描述
查詢 flashnode 連線物件,使用傳入的函式指標中定義的邏輯比較傳遞的資料
返回
成功時指向找到的 flashnode 連線裝置物件的指標,失敗時為
NULL
-
void iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess)¶
銷燬 flashnode 會話條目
引數
struct iscsi_bus_flash_session *fnode_sess指向要銷燬的 flashnode 會話條目的指標
描述
從 sysfs 中刪除 flashnode 會話條目和所有子 flashnode 連線條目
-
void iscsi_destroy_all_flashnode(struct Scsi_Host *shost)¶
銷燬所有 flashnode 會話條目
引數
struct Scsi_Host *shost指向主機資料的指標
描述
從 sysfs 中銷燬所有 flashnode 會話條目和所有相應的子 flashnode 連線條目
-
int iscsi_block_scsi_eh(struct scsi_cmnd *cmd)¶
阻塞 scsi eh 直到會話狀態轉換
引數
struct scsi_cmnd *cmd傳遞給 scsi eh 處理程式的 scsi 命令
描述
如果會話已關閉,則此函式將等待恢復定時器觸發或會話重新登入。如果恢復定時器觸發,則返回 FAST_IO_FAIL。呼叫者應將此錯誤值傳遞給 scsi eh。
-
void iscsi_unblock_session(struct iscsi_cls_session *session)¶
將會話設定為已登入並啟動 IO。
引數
struct iscsi_cls_session *sessioniscsi 會話
描述
將會話標記為準備好接受 IO。
-
void iscsi_force_destroy_session(struct iscsi_cls_session *session)¶
從核心銷燬會話
引數
struct iscsi_cls_session *session要銷燬的會話
描述
強制從核心銷燬會話。僅當用戶空間在系統關閉期間不再執行時,才應使用此方法。
-
struct iscsi_cls_conn *iscsi_alloc_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)¶
分配 iscsi 類連線
引數
struct iscsi_cls_session *sessioniscsi cls 會話
int dd_size私有驅動程式資料大小
uint32_t cid連線 ID
-
int iscsi_add_conn(struct iscsi_cls_conn *conn)¶
新增 iscsi 類連線
引數
struct iscsi_cls_conn *conniscsi cls 連線
描述
這會將 iscsi_cls_conn 公開給 sysfs,因此請確保在呼叫此函式之前初始化 sysfs 屬性的相關資源。
-
void iscsi_remove_conn(struct iscsi_cls_conn *conn)¶
從 sysfs 中刪除 iscsi 類連線
引數
struct iscsi_cls_conn *conniscsi cls 連線
描述
從 sysfs 中刪除 iscsi_cls_conn,並等待先前在 sysfs 中讀取/寫入 iscsi_cls_conn 的屬性完成。
-
int iscsi_session_event(struct iscsi_cls_session *session, enum iscsi_uevent_e event)¶
傳送會話銷燬完成事件
引數
struct iscsi_cls_session *sessioniscsi 類會話
enum iscsi_uevent_e event事件型別
序列連線 SCSI (SAS) 傳輸類¶
檔案 drivers/scsi/scsi_transport_sas.c 定義了序列連線 SCSI 的傳輸屬性,它是 SATA 的一種變體,旨在用於大型高端系統。
SAS 傳輸類包含用於處理 SAS HBA、驅動程式模型中 SAS 拓撲的近似表示以及各種 sysfs 屬性以向用戶空間公開這些拓撲和管理介面的通用程式碼。
除了基本的 SCSI 核心物件之外,此傳輸類還引入了兩個額外的中間物件:SAS PHY 由 struct sas_phy 表示,定義了 SAS HBA 或擴充套件器上的“傳出”PHY,SAS 遠端 PHY 由 struct sas_rphy 表示,定義了 SAS 擴充套件器或終端裝置上的“傳入”PHY。請注意,這純粹是一個軟體概念,PHY 和遠端 PHY 的底層硬體完全相同。
此程式碼中沒有 SAS 埠的概念,使用者可以根據 port_identifier 屬性檢視哪些 PHY 構成一個寬埠,該屬性對於埠中的所有 PHY 都是相同的。
引數
struct device *dev屬於 sas 物件的裝置
描述
刪除給定物件的所有 SAS PHY 和遠端 PHY
-
void sas_remove_host(struct Scsi_Host *shost)¶
拆除 Scsi_Host 的 SAS 資料結構
引數
struct Scsi_Host *shost已拆除的 Scsi Host
描述
刪除給定 Scsi_Host 的所有 SAS PHY 和遠端 PHY,並同時刪除 Scsi_Host。
注意
不要再在 Scsi_Host 上呼叫 scsi_remove_host(),因為它已被刪除。
-
u64 sas_get_address(struct scsi_device *sdev)¶
返回裝置的 SAS 地址
引數
struct scsi_device *sdevscsi 裝置
描述
返回 scsi 裝置的 SAS 地址
-
unsigned int sas_tlr_supported(struct scsi_device *sdev)¶
檢查 vpd 0x90 中的 TLR 位
引數
struct scsi_device *sdevscsi 裝置結構
描述
檢查是否支援傳輸層重試。如果存在 vpd 頁 0x90,則支援 TRL。
-
void sas_disable_tlr(struct scsi_device *sdev)¶
設定 TLR 標誌
引數
struct scsi_device *sdevscsi 裝置結構
描述
將 tlr_enabled 標誌設定為 0。
-
void sas_enable_tlr(struct scsi_device *sdev)¶
設定 TLR 標誌
引數
struct scsi_device *sdevscsi 裝置結構
描述
將 tlr_enabled 標誌設定為 1。
-
bool sas_ata_ncq_prio_supported(struct scsi_device *sdev)¶
檢查是否支援 ATA NCQ 命令優先順序
引數
struct scsi_device *sdevSCSI 裝置
描述
檢查 ATA 裝置是否使用 VPD 頁 89h(ATA 資訊)支援 NCQ 優先順序。由於此 VPD 頁僅針對 ATA 裝置實現,因此此函式始終為 SCSI 裝置返回 false。
引數
struct device *parent父裝置
int numberPhy 索引
描述
分配一個 SAS PHY 結構。它將新增到裝置樹中,位於 parent 指定的裝置下,該裝置必須是 Scsi_Host 或 sas_rphy。
返回
已分配的 SAS PHY,如果分配失敗,則為
NULL。
-
int sas_phy_add(struct sas_phy *phy)¶
將 SAS PHY 新增到裝置層次結構
引數
struct sas_phy *phy要新增的 PHY
描述
將 SAS PHY 釋出到系統的其餘部分。
-
void sas_phy_free(struct sas_phy *phy)¶
釋放 SAS PHY
-
void sas_phy_delete(struct sas_phy *phy)¶
刪除 SAS PHY
引數
struct sas_phy *phy要刪除的 SAS PHY
描述
刪除指定的 SAS PHY。如果 SAS PHY 有關聯的遠端 PHY,則先將其刪除。
-
int scsi_is_sas_phy(const struct device *dev)¶
檢查
struct device是否代表一個SAS PHY
引數
const struct device *dev要檢查的裝置
返回
如果裝置代表一個SAS PHY,則返回
1,否則返回0
引數
struct device *parent父裝置
int port_id埠號
描述
分配一個 SAS 埠結構。它將被新增到裝置樹中,位於由 **parent** 指定的裝置下方,該裝置必須是 Scsi_Host 或 sas_expander_device。
返回
出錯時返回NULL
引數
struct device *parent父裝置
描述
分配一個 SAS 埠結構和一個與之關聯的號碼。 此介面實際上適用於埠號沒有意義的介面卡,因此 SAS 類應該管理它們。 它將被新增到裝置樹中,位於由 **parent** 指定的裝置下方,該裝置必須是 Scsi_Host 或 sas_expander_device。
返回
出錯時返回NULL
-
int sas_port_add(struct sas_port *port)¶
將一個SAS埠新增到裝置層次結構中
引數
struct sas_port *port要新增的埠
描述
向系統的其餘部分發佈一個埠
-
void sas_port_free(struct sas_port *port)¶
釋放一個SAS埠
-
void sas_port_delete(struct sas_port *port)¶
移除 SAS 埠
引數
struct sas_port *port要移除的 SAS 埠
描述
移除指定的 SAS 埠。如果 SAS 埠有關聯的 phys,則將它們也從埠取消連結。
-
int scsi_is_sas_port(const struct device *dev)¶
檢查
struct device是否代表一個SAS埠
引數
const struct device *dev要檢查的裝置
返回
如果裝置代表一個 SAS 埠,則返回
1,否則返回0
-
struct sas_phy *sas_port_get_phy(struct sas_port *port)¶
嘗試獲取對埠成員的引用
引數
struct sas_port *port要檢查的埠
-
void sas_port_add_phy(struct sas_port *port, struct sas_phy *phy)¶
將另一個phy新增到埠以形成一個寬埠
引數
struct sas_port *port要將phy新增到的埠
struct sas_phy *phy要新增的phy
描述
當埠最初建立時,它是空的(沒有 phys)。所有埠必須至少有一個 phy 才能執行,並且所有寬埠必須至少有兩個。當前程式碼對埠和寬埠沒有區別,但是唯一可以連線到遠端裝置的物件是一個埠,所以如果埠連線到任何東西,則必須在具有 phys 的所有裝置上形成埠。
-
void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy)¶
從埠或寬埠中移除一個 phy
引數
struct sas_port *port要從中移除 phy 的埠
struct sas_phy *phy要移除的 phy
描述
此操作用於再次拆除埠。 在呼叫 sas_port_delete 之前,必須對每個埠或寬埠執行此操作。
-
struct sas_rphy *sas_end_device_alloc(struct sas_port *parent)¶
為終端裝置分配一個 rphy
引數
struct sas_port *parent哪個埠
描述
分配一個 SAS 遠端 PHY 結構,連線到 **parent**。
返回
已分配的 SAS PHY,如果分配失敗,則為
NULL。
-
struct sas_rphy *sas_expander_alloc(struct sas_port *parent, enum sas_device_type type)¶
為終端裝置分配一個 rphy
引數
struct sas_port *parent哪個埠
enum sas_device_type typeSAS_EDGE_EXPANDER_DEVICE 或 SAS_FANOUT_EXPANDER_DEVICE
描述
分配一個 SAS 遠端 PHY 結構,連線到 **parent**。
返回
已分配的 SAS PHY,如果分配失敗,則為
NULL。
-
int sas_rphy_add(struct sas_rphy *rphy)¶
將一個SAS遠端PHY新增到裝置層次結構中
引數
struct sas_rphy *rphy要新增的遠端 PHY
描述
向系統的其餘部分發佈一個 SAS 遠端 PHY。
-
void sas_rphy_free(struct sas_rphy *rphy)¶
釋放一個SAS遠端PHY
引數
struct sas_rphy *rphy要釋放的SAS遠端PHY
描述
釋放指定的SAS遠端PHY。
注意
此函式只能在尚未成功使用
sas_rphy_add()新增的遠端 PHY 上呼叫(或者已經sas_rphy_remove()掉了)。
-
void sas_rphy_delete(struct sas_rphy *rphy)¶
移除並釋放SAS遠端PHY
引數
struct sas_rphy *rphy要移除和釋放的SAS遠端PHY
描述
移除指定的SAS遠端PHY並釋放它。
-
void sas_rphy_unlink(struct sas_rphy *rphy)¶
取消連結 SAS 遠端 PHY
引數
struct sas_rphy *rphy要從其父埠取消連結的 SAS 遠端 phy
描述
移除對 rphy 的埠引用
-
void sas_rphy_remove(struct sas_rphy *rphy)¶
移除 SAS 遠端 PHY
引數
struct sas_rphy *rphy要移除的 SAS 遠端 phy
描述
移除指定的 SAS 遠端 PHY。
-
int scsi_is_sas_rphy(const struct device *dev)¶
檢查
struct device是否代表一個SAS遠端PHY
引數
const struct device *dev要檢查的裝置
返回
如果裝置代表一個 SAS 遠端 PHY,則返回
1,否則返回0
-
struct scsi_transport_template *sas_attach_transport(struct sas_function_template *ft)¶
例項化 SAS 傳輸模板
引數
struct sas_function_template *ftSAS 傳輸類函式模板
-
void sas_release_transport(struct scsi_transport_template *t)¶
釋放 SAS 傳輸模板例項
引數
struct scsi_transport_template *t傳輸模板例項
SATA 傳輸類¶
SATA 傳輸由 libata 處理,它在此目錄中有自己的文件書。
並行 SCSI (SPI) 傳輸類¶
檔案 drivers/scsi/scsi_transport_spi.c 定義了傳統(快速/寬/超)SCSI 匯流排的傳輸屬性。
-
void spi_dv_device(struct scsi_device *sdev)¶
對裝置進行域驗證
引數
struct scsi_device *sdev要驗證的 scsi 裝置
在當前執行執行緒中對給定裝置執行域驗證。 由於 DV 操作可能會休眠,因此當前執行緒必須具有使用者上下文。 也不得持有任何可能導致 DV 發出的 I/O 發生死鎖的 SCSI 相關鎖。
-
void spi_schedule_dv_device(struct scsi_device *sdev)¶
計劃對裝置進行域驗證
引數
struct scsi_device *sdev要驗證的裝置
與上面的
spi_dv_device()相同,只是 DV 將被安排在稍後的工作佇列中進行。 所有記憶體分配都是原子的,因此可以從任何上下文呼叫,包括那些持有 SCSI 鎖的上下文。
-
void spi_display_xfer_agreement(struct scsi_target *starget)¶
列印當前目標傳輸協議
引數
struct scsi_target *starget要顯示協議的目標
描述
每個 SPI 埠都需要為總線上的每個其他埠維護一個傳輸協議。 此函式列印當前協議的單行摘要; 更多詳細資訊可在 sysfs 中獲得。
-
int spi_populate_tag_msg(unsigned char *msg, struct scsi_cmnd *cmd)¶
將標記訊息放置在緩衝區中
引數
unsigned char *msg指向放置標記的區域的指標
struct scsi_cmnd *cmd指向標記的 scsi 命令的指標
底層驅動程式可以隨時呼叫它,我們將執行
旨在為特定請求建立正確型別的標記訊息。 返回標記訊息的大小。 如果此裝置停用 TCQ,則可能返回 0。
SCSI RDMA (SRP) 傳輸類¶
檔案 drivers/scsi/scsi_transport_srp.c 定義了透過遠端直接記憶體訪問的 SCSI 的傳輸屬性。
-
int srp_tmo_valid(int reconnect_delay, int fast_io_fail_tmo, long dev_loss_tmo)¶
檢查超時組合的有效性
引數
int reconnect_delay重連延遲,以秒為單位。
int fast_io_fail_tmo快速 I/O 失敗超時,以秒為單位。
long dev_loss_tmo裝置丟失超時,以秒為單位。
描述
超時引數的組合必須確保 SCSI 命令在合理的時間內完成。 因此,不允許快速 I/O 故障超時超過 SCSI_DEVICE_BLOCK_MAX_TIMEOUT,如果已停用快速 I/O 故障,也不允許 dev_loss_tmo 超過該限制。 此外,這些引數必須確保多路徑能夠及時檢測到故障路徑。 因此,不允許同時停用所有三個引數。
-
void srp_start_tl_fail_timers(struct srp_rport *rport)¶
啟動傳輸層故障計時器
引數
struct srp_rport *rportSRP 目標埠。
描述
啟動傳輸層快速 I/O 故障和裝置丟失計時器。 不要修改已啟動的計時器。
-
int srp_reconnect_rport(struct srp_rport *rport)¶
重新連線到 SRP 目標埠
引數
struct srp_rport *rportSRP 目標埠。
描述
在呼叫 reconnect() 之前阻止 SCSI 命令排隊,以便 queuecommand() 不會與來自 SCSI EH 之外的 reconnect() 併發呼叫。 這很重要,因為 reconnect() 實現可能會重新分配 queuecommand() 所需的資源。
底層驅動程式可以隨時呼叫它,我們將執行
此函式既不等待未完成的請求完成,也不嘗試中止這些請求。 在重新連線到目標埠之前,reconnect() 函式有責任完成未完成的命令。
呼叫者有責任確保 reconnect() 函式重新分配的資源在此函式進行過程中不會被使用。 一種可能的策略是從 SCSI EH 執行緒的上下文中呼叫此函式。 另一種可能的策略是在每個可由 SCSI EH 呼叫的 SCSI LLD 回撥中鎖定 rport 互斥鎖(scsi_host_template.eh_*() 函式以及 scsi_host_template.queuecommand() 函式)。
-
enum scsi_timeout_action srp_timed_out(struct scsi_cmnd *scmd)¶
SCSI 超時 EH 的 SRP 傳輸攔截
引數
struct scsi_cmnd *scmdSCSI 命令。
描述
如果在 rport 處於阻止狀態時發生超時,請要求 SCSI EH 繼續等待 (SCSI_EH_RESET_TIMER)。 否則,讓 SCSI 核心處理超時 (SCSI_EH_NOT_HANDLED)。
注意
此函式從軟中斷上下文中呼叫,並持有請求佇列鎖。
-
void srp_rport_get(struct srp_rport *rport)¶
增加 rport 引用計數
引數
struct srp_rport *rportSRP 目標埠。
-
void srp_rport_put(struct srp_rport *rport)¶
減少 rport 引用計數
引數
struct srp_rport *rportSRP 目標埠。
-
struct srp_rport *srp_rport_add(struct Scsi_Host *shost, struct srp_rport_identifiers *ids)¶
將 SRP 遠端埠新增到裝置層次結構
引數
struct Scsi_Host *shost遠端埠連線到的 scsi 主機。
struct srp_rport_identifiers *ids遠端埠的埠 ID。
描述
將埠釋出到系統的其餘部分。
-
void srp_rport_del(struct srp_rport *rport)¶
刪除 SRP 遠端埠
引數
struct srp_rport *rport要刪除的 SRP 遠端埠
描述
刪除指定的 SRP 遠端埠。
-
void srp_remove_host(struct Scsi_Host *shost)¶
拆卸 Scsi_Host 的 SRP 資料結構
引數
struct Scsi_Host *shost已拆除的 Scsi Host
描述
刪除給定 Scsi_Host 的所有 SRP 遠端埠。 必須在 SRP HBA 的 scsi_remove_host 之前呼叫。
-
void srp_stop_rport_timers(struct srp_rport *rport)¶
停止傳輸層恢復計時器
引數
struct srp_rport *rport要停止計時器的 SRP 遠端埠。
描述
必須在 srp_remove_host() 和 scsi_remove_host() 之後呼叫。 呼叫者必須持有對 rport (rport->dev) 和 SCSI host (rport->dev.parent) 的引用。
-
struct scsi_transport_template *srp_attach_transport(struct srp_function_template *ft)¶
例項化 SRP 傳輸模板
引數
struct srp_function_template *ftSRP 傳輸類函式模板
-
void srp_release_transport(struct scsi_transport_template *t)¶
釋放 SRP 傳輸模板例項
引數
struct scsi_transport_template *t傳輸模板例項
SCSI 下層¶
主機匯流排介面卡傳輸型別¶
許多現代裝置控制器使用 SCSI 命令集作為協議,透過許多不同型別的物理連線與其裝置進行通訊。
在 SCSI 語言中,能夠承載 SCSI 命令的匯流排稱為“傳輸”,而連線到此類匯流排的控制器稱為“主機匯流排介面卡 (HBA)”。
除錯傳輸¶
檔案 drivers/scsi/scsi_debug.c 模擬一個主機介面卡,該介面卡連線了可變數量的磁碟(或類似磁碟的裝置),共享一個公共的 RAM 容量。 執行大量檢查以確保我們沒有混淆塊,並且如果發現任何異常情況,核心會發生 panic。
為了更逼真,模擬裝置具有 SAS 磁碟的傳輸屬性。
待辦事項¶
並行(快速/寬/超寬)SCSI、USB、SATA、SAS、光纖通道、FireWire、ATAPI 裝置、Infiniband、並行埠、netlink...