Ottenere la lista di tutti i dispositivi PCI presenti nel sistema

Da Gambas-it.org - Wikipedia.

Per ottenere un elenco dei dispositivi PCI presenti nel proprio sistema, è possibile utilizzare le risorse della libreria libpci, che offre accesso allo spazio configurazione PCI del sistema operativo.

Per poter fruire delle sue risorse, è necessario avere installata nel sistema e richiamare in Gambas la libreria condivisa: "libpci.so.3.10.0 ".

Mostriamo un esempio pratico:

Library "libpci:3.10.0"

Private Const PCI_FILL_IDENT As Integer = 1
Private Const PCI_LOOKUP_DEVICE As Integer = 2
Private Const PCI_FILL_BASES As Integer = 4
Private Const PCI_FILL_CLASS As Integer = 32
Private Const PCI_INTERRUPT_PIN As Integer = 61

Public Struct pci_access
  method As Integer
  writeable As Integer
  buscentric As Integer
  id_file_name As Pointer
  free_id_name As Integer
  numeric_ids As Integer
  id_lookup_mode As Integer
  debugging As Integer
  PCI_PRINTF_error As Pointer
  PCI_PRINTF_warning As Pointer
  PCI_PRINTF_debug As Pointer
  devices As Pointer
  methods As Pointer
  params As Pointer
  id_hash As Pointer
  current_id_bucket As Pointer
  id_load_failed As Integer
  id_cache_status As Integer
  fd As Integer
  fd_rw As Integer
  fd_pos As Integer
  fd_vpd As Integer
  cached_dev As Pointer
End Struct

Public Struct pci_dev
  _next As Pointer
  domain As Short
  bus As Byte
  dev As Byte
  func As Byte
  known_fields As Integer
  vendor_id As Short
  device_id As Short
  device_class As Short
  irq As Integer
  base_addr[6] As Long
  size[6] As Long
  rom_base_addr As Long
  rom_size As Long
  first_cap As Pointer
  phy_slot As Pointer
  module_alias As Pointer
  access As Pointer
  methods As Pointer
  cache As Pointer
  cache_len As Integer
  hdrtype As Integer
  aux As Pointer
End Struct

' struct pci_access *pci_alloc(void)
' Initialize PCI access.
Private Extern pci_alloc() As Pci_access

' void pci_init(struct pci_access *)
Private Extern pci_init(pci_access As Pci_access)

' void pci_scan_bus(struct pci_access *acc)
' Scanning of devices.
Private Extern pci_scan_bus(acc As Pci_access)

' int pci_fill_info(struct pci_dev *, int flags)
' Fill in device information.
Private Extern pci_fill_info(pdev As Pci_dev, flags As Integer) As Integer

' u8 pci_read_byte(struct pci_dev *, int pos)
Private Extern pci_read_byte(pdev As Pci_dev, pos As Integer) As Byte

' char *pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, ...)
' Identifies different types of ID's.
Private Extern pci_lookup_name(a As Pci_access, buf As Pointer, size As Integer, flags As Integer, vendor_id As Integer, device_id As Integer) As String

' void pci_cleanup(struct pci_access *)
Private Extern pci_cleanup(acc As Pci_access)


Public Sub Main()
 
 Dim pacc As Pci_access
 Dim dev As Pci_dev
 Dim i As Integer
 Dim namebuf As New Byte[1024]
 
 pacc = pci_alloc()
 If Object.Address(pacc) == 0 Then Error.Raise("Impossibile inizializzare la Struttura 'pci_access' !")

' Inizializza la libreria "libpci":
 pci_init(pacc) 

 pci_scan_bus(pacc)
 dev = pacc.devices
  
 Do
   pci_fill_info(dev, PCI_FILL_IDENT Or PCI_FILL_BASES Or PCI_FILL_CLASS)
   i = pci_read_byte(dev, PCI_INTERRUPT_PIN)
   With dev
     Print Hex(.domain, 4); ":"; Hex(.bus, 2); ":"; Hex(.dev, 2); "."; .func;
     Print " vendor="; Hex(.vendor_id, 4); " device="; Hex(.device_id, 4); " class="; Hex(.device_class, 4);
     Print " irq="; .irq; " (pin "; i; ")"; " base0="; Hex(.base_addr[0], 4);
     Print " ("; pci_lookup_name(pacc, namebuf.Data, namebuf.Count, PCI_LOOKUP_DEVICE, .vendor_id, .device_id); ")"
     If .domain + .bus + .dev = 0 Then Break
   End With
   dev = dev._next
 Loop
 
' Chiude la libreria e libera la memoria precedentemente allocata:
 pci_cleanup(pacc)
  
End


Riferimenti