{"id":13817344,"url":"https://github.com/jaypipes/pcidb","last_synced_at":"2025-04-09T05:11:01.414Z","repository":{"id":33268481,"uuid":"144914663","full_name":"jaypipes/pcidb","owner":"jaypipes","description":"Small golang library for querying PCI database (pciids) information","archived":false,"fork":false,"pushed_at":"2024-09-21T16:08:31.000Z","size":81,"stargazers_count":45,"open_issues_count":0,"forks_count":17,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-02T04:04:05.689Z","etag":null,"topics":["discovery","golang-library","hardware","inspection-library","pci-devices","pci-id"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaypipes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-15T23:55:42.000Z","updated_at":"2025-03-23T04:25:25.000Z","dependencies_parsed_at":"2024-06-18T15:17:09.968Z","dependency_job_id":"af6611f2-1575-42fd-be0f-e57d7c20d3a2","html_url":"https://github.com/jaypipes/pcidb","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaypipes%2Fpcidb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaypipes%2Fpcidb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaypipes%2Fpcidb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaypipes%2Fpcidb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaypipes","download_url":"https://codeload.github.com/jaypipes/pcidb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247980837,"owners_count":21027808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["discovery","golang-library","hardware","inspection-library","pci-devices","pci-id"],"created_at":"2024-08-04T06:00:40.628Z","updated_at":"2025-04-09T05:11:01.384Z","avatar_url":"https://github.com/jaypipes.png","language":"Go","funding_links":[],"categories":["Misc"],"sub_categories":[],"readme":"# `pcidb` - the Golang PCI DB library\n\n[![Build Status](https://github.com/jaypipes/pcidb/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/jaypipes/pcidb/actions)\n[![Go Report Card](https://goreportcard.com/badge/github.com/jaypipes/pcidb)](https://goreportcard.com/report/github.com/jaypipes/pcidb)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)\n\n`pcidb` is a small Golang library for programmatic querying of PCI vendor,\nproduct and class information.\n\nWe currently test `pcidb` on Linux, Windows and MacOSX.\n\n## Usage\n\n`pcidb` contains a PCI database inspection and querying facility that allows\ndevelopers to query for information about hardware device classes, vendor and\nproduct information.\n\nThe `pcidb.New()` function returns a `pcidb.PCIDB` struct or an error if the\nPCI database could not be loaded.\n\n\u003e `pcidb`'s default behaviour is to first search for pci-ids DB files on the\n\u003e local host system in well-known filesystem paths. If `pcidb` cannot find a\n\u003e pci-ids DB file on the local host system, you can configure `pcidb` to fetch\n\u003e a current pci-ids DB file from the network. You can enable this\n\u003e network-fetching behaviour with the `pcidb.WithEnableNetworkFetch()` function\n\u003e or set the `PCIDB_ENABLE_NETWORK_FETCH` to a non-0 value.\n\nThe `pcidb.PCIDB` struct contains a number of fields that may be queried for\nPCI information:\n\n* `pcidb.PCIDB.Classes` is a map, keyed by the PCI class ID (a hex-encoded\n  string) of pointers to `pcidb.Class` structs, one for each class of PCI\n  device known to `pcidb`\n* `pcidb.PCIDB.Vendors` is a map, keyed by the PCI vendor ID (a hex-encoded\n  string) of pointers to `pcidb.Vendor` structs, one for each PCI vendor\n  known to `pcidb`\n* `pcidb.PCIDB.Products` is a map, keyed by the PCI product ID* (a hex-encoded\n  string) of pointers to `pcidb.Product` structs, one for each PCI product\n  known to `pcidb`\n\n**NOTE**: PCI products are often referred to by their \"device ID\". We use\nthe term \"product ID\" in `pcidb` because it more accurately reflects what the\nidentifier is for: a specific product line produced by the vendor.\n\n### Overriding the root mountpoint `pcidb` uses\n\nThe default root mountpoint that `pcidb` uses when looking for information\nabout the host system is `/`. So, for example, when looking up known PCI IDS DB\nfiles on Linux, `pcidb` will attempt to discover a pciids DB file at\n`/usr/share/misc/pci.ids`. If you are calling `pcidb` from a system that has an\nalternate root mountpoint, you can either set the `PCIDB_CHROOT` environment\nvariable to that alternate path, or call the `pcidb.New()` function with the\n`pcidb.WithChroot()` modifier.\n\nFor example, if you are executing from within an application container that has\nbind-mounted the root host filesystem to the mount point `/host`, you would set\n`PCIDB_CHROOT` to `/host` so that pcidb can find files like\n`/usr/share/misc/pci.ids` at `/host/usr/share/misc/pci.ids`.\n\nAlternately, you can use the `pcidb.WithChroot()` function like so:\n\n```go\npci := pcidb.New(pcidb.WithChroot(\"/host\"))\n```\n\n### PCI device classes\n\nLet's take a look at the PCI device class information and how to query the PCI\ndatabase for class, subclass, and programming interface information.\n\nEach `pcidb.Class` struct contains the following fields:\n\n* `pcidb.Class.ID` is the hex-encoded string identifier for the device\n  class\n* `pcidb.Class.Name` is the common name/description of the class\n* `pcidb.Class.Subclasses` is an array of pointers to\n  `pcidb.Subclass` structs, one for each subclass in the device class\n\nEach `pcidb.Subclass` struct contains the following fields:\n\n* `pcidb.Subclass.ID` is the hex-encoded string identifier for the device\n  subclass\n* `pcidb.Subclass.Name` is the common name/description of the subclass\n* `pcidb.Subclass.ProgrammingInterfaces` is an array of pointers to\n  `pcidb.ProgrammingInterface` structs, one for each programming interface\n   for the device subclass\n\nEach `pcidb.ProgrammingInterface` struct contains the following fields:\n\n* `pcidb.ProgrammingInterface.ID` is the hex-encoded string identifier for\n  the programming interface\n* `pcidb.ProgrammingInterface.Name` is the common name/description for the\n  programming interface\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n\n    \"github.com/jaypipes/pcidb\"\n)\n\nfunc main() {\n    pci, err := pcidb.New()\n    if err != nil {\n        fmt.Printf(\"Error getting PCI info: %v\", err)\n    }\n\n    for _, devClass := range pci.Classes {\n        fmt.Printf(\" Device class: %v ('%v')\\n\", devClass.Name, devClass.ID)\n        for _, devSubclass := range devClass.Subclasses {\n            fmt.Printf(\"    Device subclass: %v ('%v')\\n\", devSubclass.Name, devSubclass.ID)\n            for _, progIface := range devSubclass.ProgrammingInterfaces {\n                fmt.Printf(\"        Programming interface: %v ('%v')\\n\", progIface.Name, progIface.ID)\n            }\n        }\n    }\n}\n```\n\nExample output from my personal workstation, snipped for brevity:\n\n```\n...\n Device class: Serial bus controller ('0c')\n    Device subclass: FireWire (IEEE 1394) ('00')\n        Programming interface: Generic ('00')\n        Programming interface: OHCI ('10')\n    Device subclass: ACCESS Bus ('01')\n    Device subclass: SSA ('02')\n    Device subclass: USB controller ('03')\n        Programming interface: UHCI ('00')\n        Programming interface: OHCI ('10')\n        Programming interface: EHCI ('20')\n        Programming interface: XHCI ('30')\n        Programming interface: Unspecified ('80')\n        Programming interface: USB Device ('fe')\n    Device subclass: Fibre Channel ('04')\n    Device subclass: SMBus ('05')\n    Device subclass: InfiniBand ('06')\n    Device subclass: IPMI SMIC interface ('07')\n    Device subclass: SERCOS interface ('08')\n    Device subclass: CANBUS ('09')\n...\n```\n\n### PCI vendors and products\n\nLet's take a look at the PCI vendor information and how to query the PCI\ndatabase for vendor information and the products a vendor supplies.\n\nEach `pcidb.Vendor` struct contains the following fields:\n\n* `pcidb.Vendor.ID` is the hex-encoded string identifier for the vendor\n* `pcidb.Vendor.Name` is the common name/description of the vendor\n* `pcidb.Vendor.Products` is an array of pointers to `pcidb.Product`\n  structs, one for each product supplied by the vendor\n\nEach `pcidb.Product` struct contains the following fields:\n\n* `pcidb.Product.VendorID` is the hex-encoded string identifier for the\n  product's vendor\n* `pcidb.Product.ID` is the hex-encoded string identifier for the product\n* `pcidb.Product.Name` is the common name/description of the subclass\n* `pcidb.Product.Subsystems` is an array of pointers to\n  `pcidb.Product` structs, one for each \"subsystem\" (sometimes called\n  \"sub-device\" in PCI literature) for the product\n\n**NOTE**: A subsystem product may have a different vendor than its \"parent\" PCI\nproduct. This is sometimes referred to as the \"sub-vendor\".\n\nHere's some example code that demonstrates listing the PCI vendors with the\nmost known products:\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"sort\"\n\n    \"github.com/jaypipes/pcidb\"\n)\n\ntype ByCountProducts []*pcidb.Vendor\n\nfunc (v ByCountProducts) Len() int {\n    return len(v)\n}\n\nfunc (v ByCountProducts) Swap(i, j int) {\n    v[i], v[j] = v[j], v[i]\n}\n\nfunc (v ByCountProducts) Less(i, j int) bool {\n    return len(v[i].Products) \u003e len(v[j].Products)\n}\n\nfunc main() {\n    pci, err := pcidb.New()\n    if err != nil {\n        fmt.Printf(\"Error getting PCI info: %v\", err)\n    }\n\n    vendors := make([]*pcidb.Vendor, len(pci.Vendors))\n    x := 0\n    for _, vendor := range pci.Vendors {\n        vendors[x] = vendor\n        x++\n    }\n\n    sort.Sort(ByCountProducts(vendors))\n\n    fmt.Println(\"Top 5 vendors by product\")\n    fmt.Println(\"====================================================\")\n    for _, vendor := range vendors[0:5] {\n        fmt.Printf(\"%v ('%v') has %d products\\n\", vendor.Name, vendor.ID, len(vendor.Products))\n    }\n}\n```\n\nwhich yields (on my local workstation as of July 7th, 2018):\n\n```\nTop 5 vendors by product\n====================================================\nIntel Corporation ('8086') has 3389 products\nNVIDIA Corporation ('10de') has 1358 products\nAdvanced Micro Devices, Inc. [AMD/ATI] ('1002') has 886 products\nNational Instruments ('1093') has 601 products\nChelsio Communications Inc ('1425') has 525 products\n```\n\nThe following is an example of querying the PCI product and subsystem\ninformation to find the products which have the most number of subsystems that\nhave a different vendor than the top-level product. In other words, the two\nproducts which have been re-sold or re-manufactured with the most number of\ndifferent companies.\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"sort\"\n\n    \"github.com/jaypipes/pcidb\"\n)\n\ntype ByCountSeparateSubvendors []*pcidb.Product\n\nfunc (v ByCountSeparateSubvendors) Len() int {\n    return len(v)\n}\n\nfunc (v ByCountSeparateSubvendors) Swap(i, j int) {\n    v[i], v[j] = v[j], v[i]\n}\n\nfunc (v ByCountSeparateSubvendors) Less(i, j int) bool {\n    iVendor := v[i].VendorID\n    iSetSubvendors := make(map[string]bool, 0)\n    iNumDiffSubvendors := 0\n    jVendor := v[j].VendorID\n    jSetSubvendors := make(map[string]bool, 0)\n    jNumDiffSubvendors := 0\n\n    for _, sub := range v[i].Subsystems {\n        if sub.VendorID != iVendor {\n            iSetSubvendors[sub.VendorID] = true\n        }\n    }\n    iNumDiffSubvendors = len(iSetSubvendors)\n\n    for _, sub := range v[j].Subsystems {\n        if sub.VendorID != jVendor {\n            jSetSubvendors[sub.VendorID] = true\n        }\n    }\n    jNumDiffSubvendors = len(jSetSubvendors)\n\n    return iNumDiffSubvendors \u003e jNumDiffSubvendors\n}\n\nfunc main() {\n    pci, err := pcidb.New()\n    if err != nil {\n        fmt.Printf(\"Error getting PCI info: %v\", err)\n    }\n\n    products := make([]*pcidb.Product, len(pci.Products))\n    x := 0\n    for _, product := range pci.Products {\n        products[x] = product\n        x++\n    }\n\n    sort.Sort(ByCountSeparateSubvendors(products))\n\n    fmt.Println(\"Top 2 products by # different subvendors\")\n    fmt.Println(\"====================================================\")\n    for _, product := range products[0:2] {\n        vendorID := product.VendorID\n        vendor := pci.Vendors[vendorID]\n        setSubvendors := make(map[string]bool, 0)\n\n        for _, sub := range product.Subsystems {\n            if sub.VendorID != vendorID {\n                setSubvendors[sub.VendorID] = true\n            }\n        }\n        fmt.Printf(\"%v ('%v') from %v\\n\", product.Name, product.ID, vendor.Name)\n        fmt.Printf(\" -\u003e %d subsystems under the following different vendors:\\n\", len(setSubvendors))\n        for subvendorID, _ := range setSubvendors {\n            subvendor, exists := pci.Vendors[subvendorID]\n            subvendorName := \"Unknown subvendor\"\n            if exists {\n                subvendorName = subvendor.Name\n            }\n            fmt.Printf(\"      - %v ('%v')\\n\", subvendorName, subvendorID)\n        }\n    }\n}\n```\n\nwhich yields (on my local workstation as of July 7th, 2018):\n\n```\nTop 2 products by # different subvendors\n====================================================\nRTL-8100/8101L/8139 PCI Fast Ethernet Adapter ('8139') from Realtek Semiconductor Co., Ltd.\n -\u003e 34 subsystems under the following different vendors:\n      - OVISLINK Corp. ('149c')\n      - EPoX Computer Co., Ltd. ('1695')\n      - Red Hat, Inc ('1af4')\n      - Mitac ('1071')\n      - Netgear ('1385')\n      - Micro-Star International Co., Ltd. [MSI] ('1462')\n      - Hangzhou Silan Microelectronics Co., Ltd. ('1904')\n      - Compex ('11f6')\n      - Edimax Computer Co. ('1432')\n      - KYE Systems Corporation ('1489')\n      - ZyXEL Communications Corporation ('187e')\n      - Acer Incorporated [ALI] ('1025')\n      - Matsushita Electric Industrial Co., Ltd. ('10f7')\n      - Ruby Tech Corp. ('146c')\n      - Belkin ('1799')\n      - Allied Telesis ('1259')\n      - Unex Technology Corp. ('1429')\n      - CIS Technology Inc ('1436')\n      - D-Link System Inc ('1186')\n      - Ambicom Inc ('1395')\n      - AOPEN Inc. ('a0a0')\n      - TTTech Computertechnik AG (Wrong ID) ('0357')\n      - Gigabyte Technology Co., Ltd ('1458')\n      - Packard Bell B.V. ('1631')\n      - Billionton Systems Inc ('14cb')\n      - Kingston Technologies ('2646')\n      - Accton Technology Corporation ('1113')\n      - Samsung Electronics Co Ltd ('144d')\n      - Biostar Microtech Int'l Corp ('1565')\n      - U.S. Robotics ('16ec')\n      - KTI ('8e2e')\n      - Hewlett-Packard Company ('103c')\n      - ASUSTeK Computer Inc. ('1043')\n      - Surecom Technology ('10bd')\nBt878 Video Capture ('036e') from Brooktree Corporation\n -\u003e 30 subsystems under the following different vendors:\n      - iTuner ('aa00')\n      - Nebula Electronics Ltd. ('0071')\n      - DViCO Corporation ('18ac')\n      - iTuner ('aa05')\n      - iTuner ('aa0d')\n      - LeadTek Research Inc. ('107d')\n      - Avermedia Technologies Inc ('1461')\n      - Chaintech Computer Co. Ltd ('270f')\n      - iTuner ('aa07')\n      - iTuner ('aa0a')\n      - Microtune, Inc. ('1851')\n      - iTuner ('aa01')\n      - iTuner ('aa04')\n      - iTuner ('aa06')\n      - iTuner ('aa0f')\n      - iTuner ('aa02')\n      - iTuner ('aa0b')\n      - Pinnacle Systems, Inc. (Wrong ID) ('bd11')\n      - Rockwell International ('127a')\n      - Askey Computer Corp. ('144f')\n      - Twinhan Technology Co. Ltd ('1822')\n      - Anritsu Corp. ('1852')\n      - iTuner ('aa08')\n      - Hauppauge computer works Inc. ('0070')\n      - Pinnacle Systems Inc. ('11bd')\n      - Conexant Systems, Inc. ('14f1')\n      - iTuner ('aa09')\n      - iTuner ('aa03')\n      - iTuner ('aa0c')\n      - iTuner ('aa0e')\n```\n\n## Developers\n\nContributions to `pcidb` are welcomed! Fork the repo on GitHub and submit a pull\nrequest with your proposed changes. Or, feel free to log an issue for a feature\nrequest or bug report.\n\n### Running tests\n\nYou can run unit tests easily using the `make test` command, like so:\n\n\n```\n[jaypipes@uberbox pcidb]$ make test\ngo test github.com/jaypipes/pcidb\nok      github.com/jaypipes/pcidb    0.045s\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaypipes%2Fpcidb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaypipes%2Fpcidb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaypipes%2Fpcidb/lists"}