亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 86545 | 回復: 15
打印 上一主題 下一主題

pci_request_regions是干啥的,在驅(qū)動中需要調(diào)用嗎? [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-02-20 14:59 |只看該作者 |倒序瀏覽
今天看Linux內(nèi)核中自帶的e1000網(wǎng)卡驅(qū)動,發(fā)現(xiàn)它在probe中有如下操作:
    if ((err = pci_request_regions(pdev, e1000_driver_name)))
        return err;


但看代碼好像這里主要是把BAR0~BAR5分配到的幾個物理地址根據(jù)類似掛到iomem_resource或ioport_resource里面,從實現(xiàn)看感覺就是一個單向排序的鏈表。這個是用來干啥的?里面還檢查了地址范圍是否沖突,但這些地址范圍不是BIOS或系統(tǒng)初始化時PCI設(shè)備枚舉時映射的嗎,難道還會沖突?
也見過許多實際應(yīng)用的PCI設(shè)備驅(qū)動不調(diào)用這一操作的,這樣有啥區(qū)別?

關(guān)于這個函數(shù)用途Manual Page中講得很少,就幾句話,和源代碼中的注釋差不多;內(nèi)核Documentation/pci.txt中沒有提到這一函數(shù)。

[ 本帖最后由 Cyberman.Wu 于 2009-2-20 16:20 編輯 ]

論壇徽章:
0
2 [報告]
發(fā)表于 2009-02-27 18:18 |只看該作者
自己踢一下,沒人知道?在內(nèi)核自帶的驅(qū)動中發(fā)現(xiàn)許多地方做了這個操作。

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
3 [報告]
發(fā)表于 2009-02-27 19:13 |只看該作者
建議LZ先看看LDD3中PCI的那一章啊。里面應(yīng)該講得比較清楚

論壇徽章:
0
4 [報告]
發(fā)表于 2009-02-27 19:57 |只看該作者

回復 #3 Godbach 的帖子

1. LDD3中提都沒提到這個函數(shù),我是在看e1000網(wǎng)上驅(qū)動時看到的。從代碼知道它做了什么操作,但它的作用不怎么清楚,因為我也見過許多驅(qū)動不做這一操作的。
2. 說句實話,LDD3對于PCI驅(qū)動很是走馬觀花,不怎么樣,我是看了一本PCI Express System Architecture和一些實際驅(qū)動的代碼,然后再看標準規(guī)范才逐漸理解了的。

論壇徽章:
0
5 [報告]
發(fā)表于 2009-03-02 12:21 |只看該作者
原帖由 Cyberman.Wu 于 2009-2-27 19:57 發(fā)表
1. LDD3中提都沒提到這個函數(shù),我是在看e1000網(wǎng)上驅(qū)動時看到的。從代碼知道它做了什么操作,但它的作用不怎么清楚,因為我也見過許多驅(qū)動不做這一操作的。
2. 說句實話,LDD3對于PCI驅(qū)動很是走馬觀花,不怎么樣 ...


我記得ldd3是講了的, 你確信沒有?

論壇徽章:
0
6 [報告]
發(fā)表于 2009-03-02 13:03 |只看該作者

回復 #5 albcamus 的帖子

我在PDF格式的電子中搜索過的但沒找到,另外后面的索引中也沒找到。

論壇徽章:
0
7 [報告]
發(fā)表于 2009-03-09 16:21 |只看該作者
自己踢一腳。真的沒人知道?

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
8 [報告]
發(fā)表于 2009-03-09 23:04 |只看該作者
驅(qū)動板置頂?shù)碾娮訒芯陀蠰DD3的英文和中文版,LZ確實查找了嗎。我看LDD3的時候,PCI那一章是講過這個函數(shù)的。

論壇徽章:
0
9 [報告]
發(fā)表于 2009-03-10 02:14 |只看該作者
原帖由 Cyberman.Wu 于 2009-2-20 14:59 發(fā)表
今天看Linux內(nèi)核中自帶的e1000網(wǎng)卡驅(qū)動,發(fā)現(xiàn)它在probe中有如下操作:
    if ((err = pci_request_regions(pdev, e1000_driver_name)))
        return err;


但看代碼好像這里主要是把BAR0~BAR5分配到的 ...

Essential Linux Device Drivers 這本書對這個函數(shù)有講解,而且我覺得講得也很不錯。我把那一章都拷貝出來:
Accessing PCI Regions
PCI devices contain three addressable regions: configuration space, I/O ports, and device memory. Let's learn how to access these memory regions from a device driver.

Configuration Space
The kernel offers a set of six functions that your driver can use to operate on PCI configuration space:

pci_read_config_[byte|word|dword](struct pci_dev *pdev,
                                  int offset, int *value);
and
pci_write_config_[byte|word|dword](struct pci_dev *pdev,
                                   int offset, int value);


In the argument list, struct pci_dev is the PCI device structure, and offset is the byte position in the configuration space that you want to access. For read functions, value is a pointer to a supplied data buffer, and for write routines, it contains the data to be written.

Let's consider some examples:

To decipher the IRQ number assigned to a card function, use the following:

unsigned char irq;
pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &irq);
As per the PCI specification, offset 60 inside the PCI configuration space holds the IRQ number assigned to the card. All configuration register offsets are expressively defined in include/linux/pci_regs.h, so use PCI_INTERRUPT_LINE rather than 60 to specify this offset. Similarly, to read the PCI status register (two bytes at offset six in the configuration space), do this:

unsigned short status;
pci_read_config_word(pdev, PCI_STATUS, &status);
Only the first 64 bytes of the configuration space are standardized. The device manufacturer defines desired semantics to the rest. The Xircom card used earlier, assigns four bytes at offset 64 for power management purposes. To disable power management, the Xircom CardBus driver, drivers/net/tulip/xircom_cb.c, does this:

#define PCI_POWERMGMT 0x40
pci_write_config_dword(pdev, PCI_POWERMGMT, 0x0000);
I/O and Memory
PCI cards have up to six I/O or memory regions. I/O regions contain registers, and memory regions hold data. Video cards, for example, have I/O spaces that accommodate control registers and memory regions that map to frame buffers. Not all cards have addressable memory regions, however. The semantics of I/O and memory spaces are hardware-dependent and can be obtained from the device data sheet.

Like for configuration memory, the kernel offers a set of helpers to operate on I/O and memory regions of PCI devices:

Code View:
unsigned long pci_resource_[start|len|end|flags] (struct pci_dev *pdev, int bar);

                                          


To operate on an I/O region such as the device control registers of a PCI video card, the driver needs to do the following:

  
1.  Get the I/O base address from the appropriate base address register (bar) in the configuration space:


unsigned long io_base = pci_resource_start(pdev, bar);

This assumes that the device control registers for this card are mapped to the memory region associated with bar, whose value can range from 0 through 5, as shown in Table 10.2.


2.  Mark this region as being spoken for, using the kernel's request_region() regulatory mechanism discussed in Chapter 5, "Character Drivers":


request_region(io_base, length, "my_driver");

Here, length is the size of the control register space and my_driver identifies the region's owner. Look for the entry containing my_driver in /proc/ioports to spot this memory region.

You may instead use the wrapper function pci_request_region(), defined in drivers/pci/pci.c.


3.  Add the register's offset obtained from the data-sheet, to the base address gleaned in Step 1. Operate on this address using the inb() and outb() family of functions discussed in Chapter 5:


/* Read */
register_data = inl(io_base + REGISTER_OFFSET);
/* Use */
/* ... */
/* Write */
outl(register_data, iobase + REGISTER_OFFSET);



To operate on a memory region such as the frame buffer on the above PCI video card, follow these steps:

1.  Get the base address, length, and flags associated with the memory region:


unsigned long mmio_base   = pci_resource_start(pdev, bar);
unsigned long mmio_length = pci_resource_length(pdev, bar);
unsigned long mmio_flags  = pci_resource_flags(pdev, bar);

This assumes that this memory is mapped to the base address register, bar.


2.  Mark ownership of this region using the kernel's request_mem_region() regulatory mechanism:


request_mem_region(mmio_base, mmio_length, "my_driver");

You may instead use the wrapper function pci_request_region(), mentioned previously.


  
3.  Obtain CPU access to the device memory obtained in Step 1. Certain memory regions, such as the ones that hold registers, need to guard against side effects, so they are marked as not being prefetchable (or cacheable) by the CPU. Other regions, such as the one used in this example, can be cached. Depending on the access flag, use the appropriate function to obtain kernel virtual addresses corresponding to the mapped region:


void __iomem *buffer;
if (flags & IORESOURCE_CACHEABLE) {
  buffer = ioremap(mmio_base, mmio_length);
} else {
  buffer = ioremap_nocache(mmio_base, mmio_length);
}



To be safe, and to avoid performing the preceding checks, use the services of pci_iomap() defined in lib/iomap.c instead:

buffer = pci_iomap(pdev, bar, mmio_length);

論壇徽章:
0
10 [報告]
發(fā)表于 2009-03-10 09:52 |只看該作者

回復 #9 scutan 的帖子

Thanks. 這本書我以前下載了,但從來沒看過,只看過LDD3,看來要多看一些不同的書及代碼才行。

不過在實際的驅(qū)動中還是看到過沒有調(diào)用這一函數(shù)處理的,是一個錯誤,還是不調(diào)用關(guān)系也不大?
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP