有在研究 S3C24XX 平台的開發者應該會發現,SD 控制器驅動程式目前只支援 PIO mode,若嘗試將 DMA mode 的支援開啟,在偵測 SD 卡時就會發生問題。經過原始碼追蹤後我們可以發現到一些現象,且待我細細道來。
S3C24XX 平台的 DMA core 實作了要求佇列 (request queue) 的機制,使得它能夠接收多個 DMA 傳輸要求,並設定相關的暫存器來進行傳輸。當設定完成後,我們就可以設定 SD 控制器來觸發 DMA 控制器進行實際的資料傳輸。當要求佇列中有新的傳輸要求存在時,DMA core 會檢查 DMA 控制器是否已經在執行目前的要求;若已在執行,DMA core 就會取出新的要求,並將來源位址、目的位址以及資料長度等參數寫入暫存器中 (對暫存器寫入並不會對進行中的傳輸產生影響)。若否,DMA core 會繼續等待直到逾時為止。換言之,除非 DMA 控制器起始傳輸,否則 DMA core 是不會處理新的傳輸要求的。
MMC core 在讀取資料的過程中,預設會使用 scatter-gather DMA 來提高傳輸效率,或避免向核心要求一大塊連續的記憶體空間;然而 S3C24XX DMA 控制器並不支援此種傳輸方式,因此在執行時我們就會發現到,由於佇列中還有傳輸要求尚未設定,DMA core 不斷地在檢查 DMA 控制器是否正在執行;但是在佇列中的所有傳輸要求都被設定完成之前,SD 控制器是不會觸發 DMA 控制器來起始傳輸的 (雞生蛋,蛋生雞?),於是我們就會看到 DMA core 一直在 busy waiting,直到 time out 為止。
因此要解決這樣的問題,在向 MMC core 註冊 host controller 時,要設定該控制器同時間只能接受一個 DMA 傳輸要求 (請見 struct mmc_host 中的 max_hw_segs 及 max_phys_segs 欄位)。同時也可開啟 bounce buffer 支援以提高傳輸效率。