A new I/O memory access mechanism

Most reasonably current cards for the PCI bus (and others) provide one ormore I/O memory regions to the bus. By accessing those regions, theprocessor can communicate with the peripheral and make things happen. Alook at /proc/iomem will show the I/O memory regions which havebeen registered on a given system.

To work with an I/O memory region, a driver is supposed to map that regionwith a call to ioremap(). The return value fromioremap() is a magic cookie which can be passed to a set ofaccessor functions (with names like readb() or writel())to actually move data to or from the I/O memory. On some architectures(notably x86), I/O memory is truly mapped into the kernel's memory space,so those accessor functions turn into a straightforward pointerdereference. Other architectures require more complicated operations.

There have been some longstanding problems with this scheme. Driverswritten for the x86 architecture have often been known to simplydereference I/O memory addresses directly, rather than using the accessorfunctions. That approach works on the x86, but breaks on otherarchitectures. Other drivers, knowing that I/O memory addresses are notreal pointers, store them in integer variables; that works until theyencounter a system with a physical address space which doesn't fit into 32bits. And, in any case, readb() and friends perform no typechecking, and thus fail to catch errors which could be found at compiletime.

The 2.6.9 kernel will contain a series of changes designed to improve howthe kernel works with I/O memory. The first of these is a new__iomem annotation used to mark pointers to I/O memory. Theseannotations work much like the __user markers, except that theyreference a different address space. As with __user, the__iomem marker serves a documentation role in the kernel code; itis ignored by the compiler. When checking the code with sparse,however, developers will see a whole new set of warnings caused by codewhich mixes normal pointers with __iomem pointers, or whichdereferences those pointers.

The next step is the addition of a new set of accessor functions whichexplicitly require a pointer argument. These functions are:

    unsigned int ioread8(void __iomem *addr);
    unsigned int ioread16(void __iomem *addr);
    unsigned int ioread32(void __iomem *addr);
    void iowrite8(u8 value, void __iomem *addr);
    void iowrite16(u16 value, void __iomem *addr);
    void iowrite32(u32 value, void __iomem *addr);

By default, these functions are simply wrappers around readb() andfriends. The explicit pointer type for the argument will generatewarnings, however, if a driver passes in an integer type.

There are "string" versions of these operations:

    extern void ioread8_rep(void __iomem *port, void *buf, 
                            unsigned long count);

All of the other variants are defined as well, of course.

There is actually one other twist to these functions. Some drivers have tobe able to use either I/O memory or I/O ports, depending on thearchitecture and the device. Some such drivers have gone to considerablelengths to try to avoid duplicating code in those two cases. With the newaccessors, a driver which finds it needs to work with x86-style ports cancall:

    void __iomem *ioport_map(unsigned long port, unsigned int count);

The return value will be a cookie which allows the mapped ports to betreated as if they were I/O memory; functions like ioread8() willautomatically do the right thing. For PCI devices, there is a newfunction:

    void __iomem *pci_iomap(struct pci_dev *dev, int base, 
                            unsigned long maxlen);

For this function, the base can be either a port number or an I/Omemory address, and the right thing will be done.

As of 2.6.9-rc2, there are no in-tree users of the new interface. That canbe expected to change soon as patches get merged and the kernel janitorsget to work. For more information on the new I/O memory interface and themotivation behind it, see this explanation fromLinus.


http://lwn.net/Articles/102232/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值