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

2024-04-05 04:18

本文主要是介绍request_mem_region __request_region(iomem_resource,(start),(n),(name)),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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;
    }
}

 


这篇关于request_mem_region __request_region(iomem_resource,(start),(n),(name))的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877608

相关文章

GNSS CTS GNSS Start and Location Flow of Android15

目录 1. 本文概述2.CTS 测试3.Gnss Flow3.1 Gnss Start Flow3.2 Gnss Location Output Flow 1. 本文概述 本来是为了做Android 14 Gnss CTS 的相关环境的搭建和测试,然后在测试中遇到了一些问题,去寻找CTS源码(/cts/tests/tests/location/src/android/locat

Oracle Start With关键字

Oracle Start With关键字 前言 旨在记录一些Oracle使用中遇到的各种各样的问题. 同时希望能帮到和我遇到同样问题的人. Start With (树查询) 问题描述: 在数据库中, 有一种比较常见得 设计模式, 层级结构 设计模式, 具体到 Oracle table中, 字段特点如下: ID, DSC, PID; 三个字段, 分别表示 当前标识的 ID(主键), DSC 当

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

Vue3上传图片报错:Current request is not a multipart request

当你看到错误 "Current request is not a multipart request" 时,这通常意味着你的服务器或后端代码期望接收一个 multipart/form-data 类型的请求,但实际上并没有收到这样的请求。在使用 <el-upload> 组件时,如果你已经设置了 http-request 属性来自定义上传行为,并且遇到了这个错误,可能是因为你在发送请求时没有正确地设置

java读取resource/通过文件名获取文件类型

java读取resource java读取resource目录下文件的方法: 借助Guava库的Resource类 Resources.getResource("test.txt") 通过文件名获取文件类型 mongodb java

Oracle start with connect BY 死循环

解决办法 检查start with前有没有where条件, 如果有的话,套一层select,再 Oracle start with connect BY

使用http-request 属性替代action绑定上传URL

在 Element UI 的 <el-upload> 组件中,如果你需要为上传的 HTTP 请求添加自定义的请求头(例如,为了通过身份验证或满足服务器端的特定要求),你不能直接在 <el-upload> 组件的属性中设置这些请求头。但是,你可以通过 http-request 属性来自定义上传的行为,包括设置请求头。 http-request 属性允许你完全控制上传的行为,包括如何构建请求、发送请

code: 400, msg: Required request body is missing 错误解决

引起这个错误的原因是,请求参数按照get方式给。 应该给json字符串才对 补充: 1. @RequestBody String resource 加@RequestBody必须给json字符串,否则会报错400,记如标题错误。 不加这个的进行请求的话,其实post和get就没有什么区别了。 2. List<String> indexCodes=(List<String>)json.

FORM的ENCTYPE=multipart/form-data 时request.getParameter()值为null问题的解决

此情况发生于前台表单传送至后台java servlet处理: 问题:当Form需要FileUpload上传文件同时上传表单其他控件数据时,由于设置了ENCTYPE=”multipart/form-data” 属性,后台request.getParameter()获取的值为null 上传文件的参考代码:http://www.runoob.com/jsp/jsp-file-uploading.ht

访问controller404:The origin server did not find a current representation for the target resource

ider build->rebuild project。Rebuild:对选定的目标(Project),进行强制性编译,不管目标是否是被修改过。由于 Rebuild 的目标只有 Project,所以 Rebuild 每次花的时间会比较长。 参考:资料