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 }