request_mem_region __request_region(&iomem_resource,(start),(n),(name))

來源:互聯網
上載者:User

linux下request_mem_region的粗略理解

文章來源:http://gliethttp.cublog.cn

  Linux把基於I/O映射方式的I/O連接埠和基於記憶體映射方式的I/O連接埠資源統稱為“I/O地區”(I/O Region)。I/O Region仍然是一種I/O資源,因此它仍然可以用resource結構類型來描述。

  Linux是以一種倒置的樹形結構來管理每一類I/O資源(如:I/O連接埠、外設記憶體、DMA和IRQ)的。每一類I/O資源都對應有一顆倒置的資源樹,樹中的每一個節點都是一個resource結構,而樹的根結點root則描述了該類資源的整個資源空間。

1.結構體
  1.1>struct resource iomem_resource
={"PCI mem", 0x00000000, 0xffffffff, IORESOURCE_MEM
};
  1.2>struct resource
{
                constchar*name;
                unsignedlong start, end;
                unsignedlong flags;
                struct resource
*parent,*sibling,*child;
             };
2.調用函數
  request_mem_region(S1D_PHYSICAL_REG_ADDR,S1D_PHYSICAL_REG_SIZE,"EpsonFB_RG")
#define request_mem_region(start,n,name)
__request_region
(&iomem_resource,(start),(n),(name))
__request_region檢查是否可以安全佔用起始物理地址S1D_PHYSICAL_REG_ADDR之後的連續S1D_PHYSICAL_REG_SIZE位元組大小空間

struct resource * __request_region(struct resource
*parent,unsignedlong start,unsignedlong n,constchar*name)
{
    struct resource
*res = kmalloc(sizeof(*res), GFP_KERNEL);

    if(res){
        memset(res, 0,sizeof(*res));
        res->name
= name;
        res->start
= start;
        res->end
= start + n - 1;
        res->flags
= IORESOURCE_BUSY;

        write_lock(&resource_lock);

        for(;;){
            struct resource
*conflict;

            conflict = __request_resource(parent, res);    //sibling parent下的所有單元,檢測申請部分是否存在交疊衝突
            if(!conflict)                                
//conflict=0;申請成功,正常安置了[start,end]到相應位置
                break;
            if(conflict
!= parent){
                parent = conflict;
                if(!(conflict->flags
& IORESOURCE_BUSY))
                    continue;
            }
             kfree(res);                                   //檢測到了資源交疊衝突,kfree歸還kmalloc申請的記憶體
            res =NULL;
            break;
        }
        write_unlock(&resource_lock);
    }
    return res;
}

staticstruct resource
* __request_resource(struct resource
*root,struct resource
*new)
{
    unsignedlong start
=new->start;
    unsignedlong end
=new->end;
    struct resource
*tmp,**p;

    if(end
< start)
        return root;
    if(start
< root->start)
        return root;
    if(end
> root->end)
        return root;
    p =&root->child;                                     
//root下的第一個鏈表元素*p.[child鏈表是以I/O資源物理地址從低到高的順序排列的]
    for(;;){
        tmp =*p;
        if(!tmp
|| tmp->start > end){
            new->sibling
= tmp;
            *p
=new;
//可以從root->child=null開始我們的分析考慮,此時tmp=null,那麼第一個申請將以!tmp條件滿足而進入
//這時root->child的值為new指標,new->sibling = tmp = null;當第二次申請發生時:如果tmp->start > end成立,
//那麼,root->child的值為new指標,new->sibling = tmp;這樣就連結上了,空間分布圖如:
//child=[start,end]-->[tmp->start,tmp->end](1);如果條件tmp->start > end不成立,那麼只能是!tmp條件進入
//那麼,root->child的值不變,tmp->sibling = new;new->sibling = tmp = null這樣就連結上了,空間分布圖如:
//child=[child->start,child->end]-->[start,end](2);
//當第三次申請發生時:如果start在(2)中的[child->end,end]之間,那麼tmp->end < start將成立,繼而continue,
//此時tmp = (2)中的[start,end],因為tmp->start < end,所以繼續執行p = &tmp->slibing = null,
//因為tmp->end > start,所以資源衝突,返回(2)中的[start,end]域
//綜上的兩個邊界值情況和一個中間值情況的分析,可以知道代碼實現了一個從地地址到高地址的順序鏈表
//模型圖:childe=[a,b]-->[c,d]-->[e,f],此時有一個[x,y]需要插入進去,tmp作為sibling指標遊動
//tmp指向child=[a,b],
//tmp指向[a,b],當tmp->start>y時,插入後的連結圖為:child=[x,y]-->[a,b]-->[c,d]-->[e,f]-->null;當tmp->end>=x時,衝突返回tmp
//tmp指向[c,d],當tmp->start>y時,插入後的連結圖為:child=[a,b]-->[x,y]-->[c,d]-->[e,f]-->null;當tmp->end>=x時,衝突返回tmp
//tmp指向[e,f],當tmp->start>y時,插入後的連結圖為:child=[a,b]-->[c,d]-->[x,y]-->[e,f]-->null;當tmp->end>=x時,衝突返回tmp
//tmp指向null                  ,插入後的連結圖為:child=[a,b]-->[c,d]-->[e,f]-->[x,y]-->null;
//順利的達到了檢測衝突,順序連結的目的
            new->parent
= root;    
            returnNULL;
        }
        p =&tmp->sibling;
        if(tmp->end
< start)
            continue;
        return tmp;
    }
}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.