Merge tag 'pwm/for-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry...
[linux-2.6-microblaze.git] / Documentation / translations / zh_TW / io_ordering.txt
1 Chinese translated version of Documentation/driver-api/io_ordering.rst
2
3 If you have any comment or update to the content, please contact the
4 original document maintainer directly.  However, if you have a problem
5 communicating in English you can also ask the Chinese maintainer for
6 help.  Contact the Chinese maintainer if this translation is outdated
7 or if there is a problem with the translation.
8
9 Traditional Chinese maintainer: Hu Haowen <src.res@email.cn>
10 ---------------------------------------------------------------------
11 Documentation/driver-api/io_ordering.rst 的繁體中文翻譯
12
13 如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文
14 交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或
15 者翻譯存在問題,請聯繫繁體中文版維護者。
16
17 繁體中文版維護者: 胡皓文 Hu Haowen <src.res@email.cn>
18 繁體中文版翻譯者: 胡皓文 Hu Haowen <src.res@email.cn>
19 繁體中文版校譯者: 胡皓文 Hu Haowen <src.res@email.cn>
20
21
22 以下爲正文
23 ---------------------------------------------------------------------
24
25 在某些平台上,所謂的內存映射I/O是弱順序。在這些平台上,驅動開發者有責任
26 保證I/O內存映射地址的寫操作按程序圖意的順序達到設備。通常讀取一個「安全」
27 設備寄存器或橋寄存器,觸發IO晶片清刷未處理的寫操作到達設備後才處理讀操作,
28 而達到保證目的。驅動程序通常在spinlock保護的臨界區退出之前使用這種技術。
29 這也可以保證後面的寫操作只在前面的寫操作之後到達設備(這非常類似於內存
30 屏障操作,mb(),不過僅適用於I/O)。
31
32 假設一個設備驅動程的具體例子:
33
34         ...
35 CPU A:  spin_lock_irqsave(&dev_lock, flags)
36 CPU A:  val = readl(my_status);
37 CPU A:  ...
38 CPU A:  writel(newval, ring_ptr);
39 CPU A:  spin_unlock_irqrestore(&dev_lock, flags)
40         ...
41 CPU B:  spin_lock_irqsave(&dev_lock, flags)
42 CPU B:  val = readl(my_status);
43 CPU B:  ...
44 CPU B:  writel(newval2, ring_ptr);
45 CPU B:  spin_unlock_irqrestore(&dev_lock, flags)
46         ...
47
48 上述例子中,設備可能會先接收到newval2的值,然後接收到newval的值,問題就
49 發生了。不過很容易通過下面方法來修復:
50
51         ...
52 CPU A:  spin_lock_irqsave(&dev_lock, flags)
53 CPU A:  val = readl(my_status);
54 CPU A:  ...
55 CPU A:  writel(newval, ring_ptr);
56 CPU A:  (void)readl(safe_register); /* 配置寄存器?*/
57 CPU A:  spin_unlock_irqrestore(&dev_lock, flags)
58         ...
59 CPU B:  spin_lock_irqsave(&dev_lock, flags)
60 CPU B:  val = readl(my_status);
61 CPU B:  ...
62 CPU B:  writel(newval2, ring_ptr);
63 CPU B:  (void)readl(safe_register); /* 配置寄存器?*/
64 CPU B:  spin_unlock_irqrestore(&dev_lock, flags)
65
66 在解決方案中,讀取safe_register寄存器,觸發IO晶片清刷未處理的寫操作,
67 再處理後面的讀操作,防止引發數據不一致問題。
68