github.com/jlowellwofford/u-root@v1.0.0/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 ) 14 15 const ( 16 pciPath = "/sys/bus/pci/devices" 17 ) 18 19 type bus struct { 20 Devices []string 21 } 22 23 func onePCI(dir string) (*PCI, error) { 24 var pci PCI 25 v := reflect.TypeOf(pci) 26 for ix := 0; ix < v.NumField(); ix++ { 27 f := v.Field(ix) 28 n := f.Tag.Get("pci") 29 if n == "" { 30 continue 31 } 32 s, err := ioutil.ReadFile(filepath.Join(dir, n)) 33 if err != nil { 34 return nil, err 35 } 36 // Linux never understood /proc. 37 reflect.ValueOf(&pci).Elem().Field(ix).SetString(string(s[2 : len(s)-1])) 38 } 39 pci.VendorName, pci.DeviceName = pci.Vendor, pci.Device 40 return &pci, nil 41 } 42 43 // Read implements the BusReader interface for type bus. Iterating over each 44 // PCI bus device. 45 func (bus *bus) Read() (Devices, error) { 46 devices := make(Devices, len(bus.Devices)) 47 for i, d := range bus.Devices { 48 p, err := onePCI(d) 49 if err != nil { 50 return nil, err 51 } 52 p.Addr = filepath.Base(d) 53 p.FullPath = d 54 devices[i] = p 55 } 56 return devices, nil 57 } 58 59 // NewBusReader returns a BusReader, given a glob to match PCI devices against. 60 // If it can't glob in pciPath/g then it returns an error. 61 // We don't provide an option to do type I or PCIe MMIO config stuff. 62 func NewBusReader(g string) (busReader, error) { 63 globs, err := filepath.Glob(filepath.Join(pciPath, g)) 64 if err != nil { 65 return nil, err 66 } 67 68 return &bus{Devices: globs}, nil 69 }