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