LINUX MMC 子系統分析(五)MMC driver模塊分析

前面我們介紹了MMC 子系統驅動模型、mmc host模塊,本篇主要介紹MMC Driver模塊,在前面幾篇文章中,我們已經說明mmc 子系統已實現mmc driver,即針對所有的mmc card(除 sdio設備外,包括mmc/sd/tf等存儲卡),均可以使用該mmc driver。

下面我們分析下mmc 子系統為何實現了統一的mmc driver,主要有如下幾點:

  1. Mmc host已提供了訪問mmc card的方法(mmc_host->request);
  2. mmc/emmc/sd等協議規範均已定義mmc card(包括mmc/sd/tf等存儲卡)支持的命令格式以及狀態流轉機制、寄存器定義等信息,因此可使用統一的驅動程序實現對所有廠家的card通信(這是由協議規範規定的,比如針對nandflash驅動模塊,也不需要為nandflash設備實現特定驅動,因其協議規範也規定了nandflash需要支持的操作及通信格式等等)

基於以上幾點,並不需要針對各廠家的mmc card,實現特殊的mmc driver,因此mmc 子系

統實現了統一的mmc driver;

本次介紹的內容包括如下幾點:

一、相關的數據結構及關聯說明

二、mmc driver的probe/remove

相關的數據結構及關聯說明


針對mmc driver而言,相關的數據結構包括mmc_driver、device_driver、device、

mmc_card、mmc_part、mmc_blk_data、mmc_queue、gendisk、request_queue等;

其中mmc_driver為一個mmc card驅動的抽象;device_driver、device為linux設備驅動模型相關的數據結構(該模塊已在前面的文章中介紹,此處不再贅述);gendisk、request_queu、request_fn為塊設備模型相關的數據結構(此處不展開);mmc_blk_data、mmc_queue主要用於實現mmc block device的通用塊層與mmc host之間進行數據傳輸;而mmc_card則為mmc_driver所要驅動的外設。

這些數據結構之間的關聯如下圖所示,它們的關聯關係說明如下:

  1. Mmc_driver與mmc_card,通過藉助設備-總線-驅動模型的數據結構(device_driver、device)及接口,實現綁定與解綁操作;
  2. 針對mmc card,通過mmc_part可定義該mmc card的分區個數及分區大小等內容(mmc card中extended CSD寄存器中存儲分區信息,當通過mmc rescan查找到mmc card時,會通過讀取該寄存器的值,獲取mmc card的分區信息);
  3. mmc_blk_data用於抽象mmc block device信息,這其中包括mmc_queue、request_queue、gendisk這些數據結構;

在完成mmc_driver與mmc_card的綁定過程中,在調用mmc_driver->probe進行設備探測時,則進行mmc block device的創建,針對每一個分區,均執行如下操作:

  1. 創建mmc_blk_data類型的變量,即為每一個分區均創建對應的通用塊設備(gendisk類型);
  2. 創建mmc_queue,併為其創建對應的線程及處理接口(主要用於處理來自塊I/O子系統的請求);
  3. 針對對mmc_queue,為其創建request_queue及其請求方法mmc_request_fn,並與gendisk進行關聯;
  4. 將gendisk註冊至塊I/O子系統中,從而將本分區對應的通用塊設備註冊至塊設備對應的bdev_map中,類似於字符設備的cdev_map;


本數據結構體包括了mmc driver 子系統、設備-總線-驅動模型、塊設備驅動模型、mmc host子系統這幾個模塊。針對mmc driver的probe而言,也就是完成如下圖的數據結構間的關聯(remove接口即解除這些數據結構間的關聯)。

LINUX MMC 子系統分析(五)MMC driver模塊分析

mmc_driver 數據結構

LINUX MMC 子系統分析(五)MMC driver模塊分析

該數據結構主要包含了device_driver類型的成員,並定義了probe、remove、suspend、resume四個函數指針;這四個函數指針的功能與device_driver中對應的函數指針時對應的。

struct mmc_card數據結構

該數據結構已在上一篇文章中說明,此處不再贅述;

struct mmc_part數據結構

該數據結構用於描述一個mmc card 分區,主要包括分區大小、分區的類型、分區名稱、是否為只讀分區等信息。mmc card中extended CSD寄存器中存儲分區信息,當通過mmc rescan查找到mmc card時,會通過讀取該寄存器的值,獲取mmc card的分區信息

LINUX MMC 子系統分析(五)MMC driver模塊分析

struct mmc_blk_data數據結構

該數據結構用於抽象一個mmc card 分區對應的block device的數據信息,其中包括:

  1. 該分區對應的通用磁盤設備gendisk,用於將該分區註冊至塊設備層,以便應用程序可通過塊設備I/O訪問該分區;
  2. mmc_queue用於抽象mmc 塊設備的請求隊列,該數據結構中包括了塊設備請求隊列成員(request_queue及其訪問方法,用於處理塊I/O層的數據請求信息,並實現將請求分發給mmc host,進而完成與mmc card的數據通信);
  3. 鏈表成員part用於將該mmc card所有分區對應的mmc_blk_data變量鏈接至一起;
  4. force_ro、power_ro_lock主要用於描述該分區對應塊設備的設備屬性信息。


LINUX MMC 子系統分析(五)MMC driver模塊分析

struct mmc_queue數據結構

該數據結構用於描述塊設備I/O的request請求,該數據結構包含的內容如下:

  1. card用於指向該隊列對應的mmc_card;
  2. thread用於描述該mmc_queue對應的線程,該線程主要用於處理所有從塊I/O層下發的請求(request_queue);
  3. request_queue類型的變量用於向塊I/O層註冊request_queue及其請求方法,以便塊I/O層可以將上層的數據請求下發至mmc block層;
  4. issue_fn用於mmc block層將數據請求下發給mmc host層,由mmc host層繼續實現數據請求的處理。


LINUX MMC 子系統分析(五)MMC driver模塊分析

Mmc block層的塊I/O請求處理

Mmc block層主要藉助mmc_queue類型的變量實現塊i/o請求,mmc block層提供了塊i/o請求處理的線程。塊i/o層接口層通過調用mmc block層的request方法(即request_queue->request_fn,即mmc_request_fn接口),該方法通過調用wake_up_process接口,喚醒mmc block層的塊i/o處理線程,該線程處理接口則調用mq->issue_fn進行i/o請求的分發,即調用mmc_blk_issue_rq接口,該接口通過一系統的接口調用,最終即調用mmc_host->ops->request,通過mmc_host提供的方法,實現與mmc_card的通信操作。Mmc block層的塊i/o處理流程如下所示。

LINUX MMC 子系統分析(五)MMC driver模塊分析

mmc driver的probe/remove

上面介紹了mmc driver層相關的數據結構,通過這些數據結構間的關聯圖,基本上對mmc driver 的probe/remove接口也

有了一定的瞭解,而mmc driver的probe/remove接口,也就是完成上述數據結構間的關聯的建立與消除。

mmc_driver的定義如註冊

mmc_driver的定義如下,該driver的名稱為“mmcblk”,主要實現了probe/remove接口以及suspend/resume接口(這兩個接口主要用於電源管理)。

LINUX MMC 子系統分析(五)MMC driver模塊分析

mmc_driver與mmc_card的綁定流程

mmc_driver與mmc_card藉助設備-總線-驅動模型提供的接口完成,mmc_driver與mmc_card綁定,並執行mmc_driver->probe接口。mmc_driver、mmc_card、mmc_bus之間的綁定流程如下所示:

  1. 通過driver_register與device_register,從而完成mmc_driver、mmc_card、mmc_bus之間的綁定。

(當mmc rescan一個mmc card後,則會創建mmc card,並同時調用device_register,將該mmc_card註冊至mmc_bus中,並觸發__device_attach,從而完成mmc_card與mmc_driver的綁定,並調用mmc_driver->probe,即調用mmc_blk_probe接口,實現mmc block device的創建及註冊流程。)

LINUX MMC 子系統分析(五)MMC driver模塊分析

mmc_blk_probe

mmc_blk_probe實現的功能如下:

針對該mmc card的每一個分區,均執行如下操作:

  1. 為每一個分區,創建對應的通用磁盤設備gendisk;
  2. 設置gendisk的fops為mmc_bdops;
  3. 為每一個通用磁盤設備,均創建request_queue及其處理方法;
  4. 為該通用磁盤設備創建mmc block塊i/o請求機制;
  5. 將該分區對應的通用磁盤設備註冊至塊設備i/o中,以便應用層可通過塊設備訪問該mmc card 分區。


LINUX MMC 子系統分析(五)MMC driver模塊分析

mmc_driver與mmc_card的解綁流程

當mmc card rescan機制,檢測到mmc card移除後,在mmc card release的過程中,即調用device_unregiser接口,完成解綁流程,從而觸發mmc_blk_remove接口的調用,完成解綁操作。而mmc_blk_remove接口的主要功能如下:

針對每一個mmc card分區,均執行如下操作:

  1. 將該分區對應的mmc 塊請求處理機制刪除;
  2. 將該分區對應的通用磁盤設備從塊設備模塊中移除;
  3. 解除mmc_card與mmc_host的關聯;


LINUX MMC 子系統分析(五)MMC driver模塊分析

以上即為本篇文章的主要內容,本篇文章主要說明mmc_driver與mmc_card的綁定與解綁流程,並說明了mmc block device的創建與刪除流程等內容,本章的內容不需要驅動開發人員進行更改,這些內容均為mmc子系統實現,此處主要用於幫助我們理解mmc子系統。


分享到:


相關文章: