生成pci设备树的简单实现
来源:互联网 发布:地下城网络中断啥毛病 编辑:程序博客网 时间:2024/05/22 03:16
2015-09-16
系统的所有pci设备记录在/sys/bus/pci/devices目录下面:
而如果pci地址下连接有其他子设备的话,可以在对应的目录下找到其他的pci地址:
可以看到0000:00:11.0下连接有0000:02:00.0, 0000:02:01.0, 0000:02:02.0, 0000:02:03.0四个设备。
所以,通过分析/sys/bus/pci/devices目录结构,就可以简单生成pci设备的树形结构。
具体过程如下:
1.读取所有的pci地址(/sys/bus/pci/devices)
承载pci信息的结构体定义如下:
/*****************************/typedef struct _pci_data { char caPCIAddr[ NAMELEN ]; char caPCIClassId[ NAMELEN ]; char caPCIClassDesc[ NAMELEN ]; char caPCIDomain[ NAMELEN ]; char caPCIBus[ NAMELEN ]; char caPCISlot[ NAMELEN ]; char caPCIFunction[ NAMELEN ]; char caPCIProductId[ NAMELEN ]; char caPCIVendorId[ NAMELEN ];} st_pci_data; typedef struct _pci_node{ st_pci_data data; struct _pci_node *next; struct _pci_node *children;} st_pci_node;/****************************/intget_all_pci_devices( st_pci_node **stppPCIs ){ DIR *fpDir = NULL; struct dirent *stpEntry = NULL; st_pci_node *stpCur = NULL; if( ( fpDir = opendir( CPCIPATH ) ) == NULL ) { fprintf( stderr, "[%s:%d]opendir error: %s\n", _FL_, strerror( errno ) ); return -1; } while( ( stpEntry = readdir( fpDir ) ) != NULL ) { st_pci_node *stpPCITmp = NULL; /* filter the '.' and '..' */ if( strcmp( stpEntry->d_name, "." ) == 0 || strcmp( stpEntry->d_name, ".." ) == 0 ) continue; /* allocate a new pci node */ stpPCITmp = malloc( sizeof( st_pci_node ) ); if( stpPCITmp == NULL ) { fprintf( stderr, "[%s:%d]malloc error: %s\n", _FL_, strerror( errno ) ); return -1; } /* init the pci node */ init_pci_node( stpPCITmp ); /* ** fill the pci node ** pci address(domain:bus:slot.function) ** pci domain bus slot function */ strcpy( stpPCITmp->data.caPCIAddr, stpEntry->d_name ); split_pci_addr( stpPCITmp->data.caPCIAddr, stpPCITmp->data.caPCIDomain, stpPCITmp->data.caPCIBus, stpPCITmp->data.caPCISlot, stpPCITmp->data.caPCIFunction ); get_pci_vendor_id( stpPCITmp->data.caPCIAddr, stpPCITmp->data.caPCIVendorId ); get_pci_product_id( stpPCITmp->data.caPCIAddr, stpPCITmp->data.caPCIProductId ); get_pci_class_id( stpPCITmp->data.caPCIAddr, stpPCITmp->data.caPCIClassId ); get_pci_class_desc( stpPCITmp->data.caPCIClassId, stpPCITmp->data.caPCIClassDesc ); if( stpCur == NULL ) *stppPCIs = stpPCITmp; else stpCur->next = stpPCITmp; stpCur = stpPCITmp; } return 0;}
2.再分别读取单个pci地址下的目录节点,和步骤1下的pci地址比较,将找到的pci地址,作为当前pci地址的子节点
intgenerate_pci_tree( st_pci_node **stppPCIs ){ st_pci_node *stpCur = *stppPCIs; st_pci_node *stpPre = NULL; st_pci_node *stpAim = NULL; char caPath[ NAMELEN ] = { 0 }; while( stpCur != NULL ) { DIR *fpDir = NULL; struct dirent *stpEntry = NULL; strcpy( caPath, CPCIPATH ); strcat( caPath, stpCur->data.caPCIAddr ); if( ( fpDir = opendir( caPath ) ) == NULL ) { fprintf( stderr, "[%s:%d]opendir error: %s\n", _FL_, strerror( errno ) ); return -1; } while( ( stpEntry = readdir( fpDir ) ) != NULL ) { if( search_pci_node( *stppPCIs, stpEntry->d_name, &stpPre, &stpAim ) ) { if( *stppPCIs == stpAim ) *stppPCIs = ( *stppPCIs )->next; /* first node is the child of current node */ else stpPre->next = stpAim->next; stpAim->next = stpCur->children; stpCur->children = stpAim; } } closedir( fpDir ); if( stpCur->children != NULL ) generate_pci_tree( &( stpCur->children ) ); stpCur = stpCur->next; } return 0;}
3.将生成的pci树输出到xml文件
intprint_pci_xml_file( char *cpXmlFileName, st_pci_node *stpPCIs ){ xmlDocPtr pXmlDoc = NULL; xmlNodePtr pXmlRootNode = NULL; xmlChar *pXmlString = NULL; int iSize = 0; xmlKeepBlanksDefault( 0 ); pXmlDoc = xmlNewDoc( BAD_CAST "1.0" ); pXmlRootNode = xmlNewNode( NULL, BAD_CAST "pci" ); xmlDocSetRootElement( pXmlDoc, pXmlRootNode ); print_pci_xml_node( pXmlRootNode, stpPCIs ); xmlSaveFormatFile( cpXmlFileName, pXmlDoc, 1 ); xmlDocDumpFormatMemoryEnc( pXmlDoc, &pXmlString, &iSize, "UTF-8", 1 ); xmlFree( pXmlString ); xmlFreeDoc( pXmlDoc ); xmlMemoryDump(); return 0;}intprint_pci_xml_node( xmlNodePtr pXmlParent, st_pci_node *stpPCIs ){ while( stpPCIs != NULL ) { xmlNodePtr xmlCurPtr = xmlNewNode( NULL, BAD_CAST stpPCIs->data.caPCIClassDesc ); xmlAddChild( pXmlParent, xmlCurPtr ); xmlSetProp( xmlCurPtr, BAD_CAST "ven_id", BAD_CAST ( stpPCIs->data.caPCIVendorId ) ); xmlSetProp( xmlCurPtr, BAD_CAST "dev_id", BAD_CAST ( stpPCIs->data.caPCIProductId ) ); xmlSetProp( xmlCurPtr, BAD_CAST "addr", BAD_CAST ( stpPCIs->data.caPCIAddr ) ); if( stpPCIs->children != NULL ) print_pci_xml_node( xmlCurPtr, stpPCIs->children ); stpPCIs = stpPCIs->next; } return 0;}
4.运行结果如下:
5.源代码
http://download.csdn.net/detail/qq123386926/9112375
0 0
- 生成pci设备树的简单实现
- fsl_e500 pci设备驱动vxworks的实现
- PCI设备的初始化
- pci设备的初始化
- pci设备的初始化
- pci设备的初始化
- 嵌入式Linux下PCI设备驱动的设计与实现
- pci设备的枚举(转)
- PCI设备内存的访问
- pci设备的枚举(转)
- PCI设备的地址空间
- 枚举PCI设备的讨论
- PCI设备的地址空间
- PCI设备的配置空间
- PCI设备的地址空间
- PCI设备的地址空间
- PCI设备的地址空间
- PCI设备的地址空间
- Static关键字
- Objective-C Runtime 运行时之四:Method Swizzling
- NSDate的简单总结
- 服务器端发送UDP数据包客户端未收到问题解决
- 仿QQ对话框
- 生成pci设备树的简单实现
- 网络七层架构
- HDOJ 2896 病毒侵袭
- javaEE --- Hibernate
- 小猫统计——自定义数据汇总(二)
- dup函数
- 解决移进/规约冲突
- Objective-C Runtime 运行时之五:协议与分类
- 111