github.com/jaypipes/ghw@v0.21.1/pkg/accelerator/accelerator_linux.go (about)

     1  // Use and distribution licensed under the Apache license version 2.
     2  //
     3  // See the COPYING file in the root project directory for full text.
     4  //
     5  
     6  package accelerator
     7  
     8  import (
     9  	"github.com/jaypipes/ghw/pkg/context"
    10  	"github.com/jaypipes/ghw/pkg/pci"
    11  )
    12  
    13  // PCI IDs list available at https://admin.pci-ids.ucw.cz/read/PD
    14  const (
    15  	pciClassProcessingAccelerator    = "12"
    16  	pciSubclassProcessingAccelerator = "00"
    17  	pciClassController               = "03"
    18  	pciSubclass3DController          = "02"
    19  	pciSubclassDisplayController     = "80"
    20  )
    21  
    22  var (
    23  	acceleratorPCIClasses = map[string][]string{
    24  		pciClassProcessingAccelerator: []string{
    25  			pciSubclassProcessingAccelerator,
    26  		},
    27  		pciClassController: []string{
    28  			pciSubclass3DController,
    29  			pciSubclassDisplayController,
    30  		},
    31  	}
    32  )
    33  
    34  func (i *Info) load() error {
    35  	accelDevices := make([]*AcceleratorDevice, 0)
    36  
    37  	// get PCI devices
    38  	pciInfo, err := pci.New(context.WithContext(i.ctx))
    39  	if err != nil {
    40  		i.ctx.Warn("error loading PCI information: %s", err)
    41  		return nil
    42  	}
    43  
    44  	// Prepare hardware filter based in the PCI Class + Subclass
    45  	isAccelerator := func(dev *pci.Device) bool {
    46  		class := dev.Class.ID
    47  		subclass := dev.Subclass.ID
    48  		if subclasses, ok := acceleratorPCIClasses[class]; ok {
    49  			if slicesContains(subclasses, subclass) {
    50  				return true
    51  			}
    52  		}
    53  		return false
    54  	}
    55  
    56  	// This loop iterates over the list of PCI devices and filters them based on discovery criteria
    57  	for _, device := range pciInfo.Devices {
    58  		if !isAccelerator(device) {
    59  			continue
    60  		}
    61  		accelDev := &AcceleratorDevice{
    62  			Address:   device.Address,
    63  			PCIDevice: device,
    64  		}
    65  		accelDevices = append(accelDevices, accelDev)
    66  	}
    67  
    68  	i.Devices = accelDevices
    69  	return nil
    70  }
    71  
    72  // TODO: delete and just use slices.Contains when the minimal golang version we support is 1.21
    73  func slicesContains(s []string, v string) bool {
    74  	for i := range s {
    75  		if v == s[i] {
    76  			return true
    77  		}
    78  	}
    79  	return false
    80  }