github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/pci/pci_linux.go (about)

     1  // Copyright 2012-2017 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package pci
     6  
     7  //go:generate go run gen.go
     8  
     9  import (
    10  	"io/ioutil"
    11  	"path/filepath"
    12  	"reflect"
    13  	"sort"
    14  )
    15  
    16  const (
    17  	pciPath = "/sys/bus/pci/devices"
    18  )
    19  
    20  type bus struct {
    21  	Devices []string
    22  }
    23  
    24  func onePCI(dir string) (*PCI, error) {
    25  	var pci PCI
    26  	v := reflect.TypeOf(pci)
    27  	for ix := 0; ix < v.NumField(); ix++ {
    28  		f := v.Field(ix)
    29  		n := f.Tag.Get("pci")
    30  		if n == "" {
    31  			continue
    32  		}
    33  		s, err := ioutil.ReadFile(filepath.Join(dir, n))
    34  		if err != nil {
    35  			return nil, err
    36  		}
    37  		// Linux never understood /proc.
    38  		reflect.ValueOf(&pci).Elem().Field(ix).SetString(string(s[2 : len(s)-1]))
    39  	}
    40  	pci.VendorName, pci.DeviceName = pci.Vendor, pci.Device
    41  	return &pci, nil
    42  }
    43  
    44  // NewBusReader returns a BusReader, given a ...glob to match PCI devices against.
    45  // If it can't glob in pciPath/g then it returns an error.
    46  // For convenience, we use * as the glob if none are supplied.
    47  // We don't provide an option to do type I or PCIe MMIO config stuff.
    48  func NewBusReader(globs ...string) (BusReader, error) {
    49  	if len(globs) == 0 {
    50  		globs = []string{"*"}
    51  	}
    52  	var exp []string
    53  	for _, g := range globs {
    54  		gg, err := filepath.Glob(filepath.Join(pciPath, g))
    55  		if err != nil {
    56  			return nil, err
    57  		}
    58  		exp = append(exp, gg...)
    59  	}
    60  	// uniq
    61  	var u = map[string]struct{}{}
    62  	for _, e := range exp {
    63  		u[e] = struct{}{}
    64  	}
    65  	exp = []string{}
    66  	for v := range u {
    67  		exp = append(exp, v)
    68  	}
    69  	// sort. This might even sort like a shell would do it.
    70  	sort.Strings(exp)
    71  	return &bus{Devices: exp}, nil
    72  }