以我们家Intel为代表的i386系列处理器中,内存和外部IO是独立编址独立寻址的,于是有一个地址空间叫做内存空间,另有一个地址空间叫做I/O空间.也就是说,从处理器的角度来说,i386提供了一些单独的指令用来访问I/O空间.换言之,访问I/O空间和访问普通的内存得使用不同的指令.而在一些玩嵌入式的处理器中,比如PowerPC,他们家就只使用一个空间,那就是内存空间,那像这种情况,外设的I/O端口的物理地址就被映射到内存地址空间中,这就是传说中的Memory-mapped,内存映射.而我们家那种情况,外设的I/O端口的物理地址就被映射到I/O地址空间中,这就是传说中的I/O-mapped,即I/O映射.
要使用I/O内存首先要申请,然后要映射,而要使用I/O端口首先要申请,或者叫请求,对于I/O端口的请求意思是让内核知道你要访问这个端口,这样内核知道了以后它就不会再让别人也访问这个端口了.毕竟这个世界僧多粥少啊.申请I/O端口的函数是request_region,这个函数来自include/linux/ioport.h,
116 /* Convenience shorthand with allocation */
117 #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
118 #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name))
119 #define rename_region(region, newname) do { (region)->name = (newname); } while (0)
120
121 extern struct resource * __request_region(struct resource *,
122 resource_size_t start,
123 resource_size_t n, const char *name);
这里我们看到的那个request_mem_region是申请I/O内存用的.申请了之后,还需要使用ioremap或者ioremap_nocache函数来映射.
对于request_region,三个参数start,n,name表示你想使用从start开始的size为n的I/O port资源,name自然就是你的名字了.这三个概念在我们刚才贴出来的cat /proc/ioports里面显示的很清楚,name就是uhci-hcd.
request_region函数如果成功将返回非NULL,失败了才返回NULL.所以代码的意思就是一旦成功就跳出循环.反之,如果循环都结束了还未能请求到,那就说明出错了.那么你说为何一旦成功就跳出循环?老实说,这个问题足足困扰了我13秒钟,别小看13秒钟,有这么长时间刘翔都已经完成一次110米跨栏了.让spec来告诉你.
http://blog.csdn.net/fudan_abc/article/details/1811451