162306a36Sopenharmony_ciChinese translated version of Documentation/driver-api/io_ordering.rst 262306a36Sopenharmony_ci 362306a36Sopenharmony_ciIf you have any comment or update to the content, please contact the 462306a36Sopenharmony_cioriginal document maintainer directly. However, if you have a problem 562306a36Sopenharmony_cicommunicating in English you can also ask the Chinese maintainer for 662306a36Sopenharmony_cihelp. Contact the Chinese maintainer if this translation is outdated 762306a36Sopenharmony_cior if there is a problem with the translation. 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciTraditional Chinese maintainer: Hu Haowen <src.res.211@gmail.com> 1062306a36Sopenharmony_ci--------------------------------------------------------------------- 1162306a36Sopenharmony_ciDocumentation/driver-api/io_ordering.rst 的繁體中文翻譯 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 1462306a36Sopenharmony_ci交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或 1562306a36Sopenharmony_ci者翻譯存在問題,請聯繫繁體中文版維護者。 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci繁體中文版維護者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 1862306a36Sopenharmony_ci繁體中文版翻譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 1962306a36Sopenharmony_ci繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci以下爲正文 2362306a36Sopenharmony_ci--------------------------------------------------------------------- 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci在某些平台上,所謂的內存映射I/O是弱順序。在這些平台上,驅動開發者有責任 2662306a36Sopenharmony_ci保證I/O內存映射地址的寫操作按程序圖意的順序達到設備。通常讀取一個「安全」 2762306a36Sopenharmony_ci設備寄存器或橋寄存器,觸發IO晶片清刷未處理的寫操作到達設備後才處理讀操作, 2862306a36Sopenharmony_ci而達到保證目的。驅動程序通常在spinlock保護的臨界區退出之前使用這種技術。 2962306a36Sopenharmony_ci這也可以保證後面的寫操作只在前面的寫操作之後到達設備(這非常類似於內存 3062306a36Sopenharmony_ci屏障操作,mb(),不過僅適用於I/O)。 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci假設一個設備驅動程的具體例子: 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci ... 3562306a36Sopenharmony_ciCPU A: spin_lock_irqsave(&dev_lock, flags) 3662306a36Sopenharmony_ciCPU A: val = readl(my_status); 3762306a36Sopenharmony_ciCPU A: ... 3862306a36Sopenharmony_ciCPU A: writel(newval, ring_ptr); 3962306a36Sopenharmony_ciCPU A: spin_unlock_irqrestore(&dev_lock, flags) 4062306a36Sopenharmony_ci ... 4162306a36Sopenharmony_ciCPU B: spin_lock_irqsave(&dev_lock, flags) 4262306a36Sopenharmony_ciCPU B: val = readl(my_status); 4362306a36Sopenharmony_ciCPU B: ... 4462306a36Sopenharmony_ciCPU B: writel(newval2, ring_ptr); 4562306a36Sopenharmony_ciCPU B: spin_unlock_irqrestore(&dev_lock, flags) 4662306a36Sopenharmony_ci ... 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci上述例子中,設備可能會先接收到newval2的值,然後接收到newval的值,問題就 4962306a36Sopenharmony_ci發生了。不過很容易通過下面方法來修復: 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci ... 5262306a36Sopenharmony_ciCPU A: spin_lock_irqsave(&dev_lock, flags) 5362306a36Sopenharmony_ciCPU A: val = readl(my_status); 5462306a36Sopenharmony_ciCPU A: ... 5562306a36Sopenharmony_ciCPU A: writel(newval, ring_ptr); 5662306a36Sopenharmony_ciCPU A: (void)readl(safe_register); /* 配置寄存器?*/ 5762306a36Sopenharmony_ciCPU A: spin_unlock_irqrestore(&dev_lock, flags) 5862306a36Sopenharmony_ci ... 5962306a36Sopenharmony_ciCPU B: spin_lock_irqsave(&dev_lock, flags) 6062306a36Sopenharmony_ciCPU B: val = readl(my_status); 6162306a36Sopenharmony_ciCPU B: ... 6262306a36Sopenharmony_ciCPU B: writel(newval2, ring_ptr); 6362306a36Sopenharmony_ciCPU B: (void)readl(safe_register); /* 配置寄存器?*/ 6462306a36Sopenharmony_ciCPU B: spin_unlock_irqrestore(&dev_lock, flags) 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci在解決方案中,讀取safe_register寄存器,觸發IO晶片清刷未處理的寫操作, 6762306a36Sopenharmony_ci再處理後面的讀操作,防止引發數據不一致問題。 6862306a36Sopenharmony_ci 69