/* * Hardware Information, version 0.3 * Copyright (C) 2003 Leandro Pereira * * May be modified and/or distributed under the terms of GNU GPL version 2. * */ #include "hardinfo.h" #include "pci.h" void hi_show_pci_info(MainWindow *mainwindow, PCIDevice *device) { gchar *buf; if(!device) return; gtk_window_set_title(GTK_WINDOW(mainwindow->det_window->window), device->category); detail_window_set_icon(mainwindow->det_window, IMG_PREFIX "pci.png"); detail_window_set_dev_name(mainwindow->det_window, device->name); detail_window_set_dev_type(mainwindow->det_window, device->category); if (device->irq) detail_window_append_info_int(mainwindow->det_window, "IRQ", device->irq, FALSE); if(device->io_addr) { buf = g_strdup_printf(_("0x%x to 0x%x"), device->io_addr, device->io_addr_end); detail_window_append_info(mainwindow->det_window, _("I/O Address"), buf); g_free(buf); } if(device->memory) { buf = g_strdup_printf(_("%d%s"), (device->memory <= 1024) ? device->memory : device->memory / 1000, (device->memory <= 1024) ? "bytes" : "KB"); detail_window_append_info(mainwindow->det_window, _("Memory"), buf); g_free(buf); } if(device->freq) { buf = g_strdup_printf(_("%dMHz"), device->freq); detail_window_append_info(mainwindow->det_window, _("Frequency"), buf); g_free(buf); } if (device->latency) detail_window_append_info_int(mainwindow->det_window, _("Latency"), device->latency, FALSE); detail_window_append_info(mainwindow->det_window, _("Bus master"), (gchar*)((device->bus_master) ? _("Yes") : _("No"))); detail_window_append_separator(mainwindow->det_window); detail_window_append_info_int(mainwindow->det_window, _("Domain"), device->domain, FALSE); detail_window_append_info_int(mainwindow->det_window, _("Bus"), device->bus, FALSE); detail_window_append_info_int(mainwindow->det_window, _("Device"), device->device, FALSE); detail_window_append_info_int(mainwindow->det_window, _("Function"), device->function, FALSE); } #ifdef USE_LSPCI PCIDevice *hi_scan_pci(void) { FILE *lspci; gchar buffer[256], *buf; gint n=0; PCIDevice *pci_dev = NULL, *pci; pci = NULL; lspci = popen(LSPCI, "r"); if(!lspci) return NULL; while(fgets(buffer, 256, lspci)){ buf = g_strstrip(buffer); if(!strncmp(buf, "Flags", 5)){ gint irq=0, freq=0, latency=0, i; gchar **list; buf+=7; pci_dev->bus_master = FALSE; list = g_strsplit(buf, ", ", 10); for (i = 0; i <= 10; i++) { if(!list[i]) break; if(!strncmp(list[i], "IRQ", 3)) sscanf(list[i], "IRQ %d", &irq); else if(strstr(list[i], "Mhz")) sscanf(list[i], "%dMhz", &freq); else if(!strncmp(list[i], "bus master", 10)) pci_dev->bus_master = TRUE; else if(!strncmp(list[i], "latency", 7)) sscanf(list[i], "latency %d", &latency); } g_strfreev(list); if (irq) pci_dev->irq = irq; if (freq) pci_dev->freq = freq; if (latency) pci_dev->latency = latency; } else if(!strncmp(buf, "Memory at", 9) && strstr(buf, "[size=")) { gulong mem; gchar unit; walk_until('['); sscanf(buf, "[size=%ld%c", &mem, &unit); mem *= (unit == ']') ? 1 : (unit == 'K') ? 1024 : (unit == 'M') ? 1024 * 1000 : (unit == 'G') ? 1024 * 1000 * 1000 : 1; pci_dev->memory += mem; } else if(!strncmp(buf, "I/O", 3)){ guint io_addr, io_size; sscanf(buf, "I/O ports at %x [size=%d]", &io_addr, &io_size); pci_dev->io_addr = io_addr; pci_dev->io_addr_end = io_addr+io_size; } else if((buf[0] >= '0' && buf[0] <= '9') && buf[4] == ':'){ gint bus, device, function, domain; gpointer start, end; pci_dev = g_new0(PCIDevice, 1); pci_dev->next = pci; pci = pci_dev; sscanf(buf, "%x:%x:%x.%d", &domain, &bus, &device, &function); pci_dev->domain = domain; pci_dev->bus = bus; pci_dev->device = device; pci_dev->function = function; walk_until(' '); start = buf; walk_until(':'); end = buf+1; *buf=0; buf = start+1; pci_dev->category = g_strdup(buf); buf = end; start = buf; walk_until('('); *buf = 0; buf = start+1; pci_dev->name = g_strdup(buf); n++; } } pclose(lspci); return pci; } #else #warning Using /proc/pci is deprecated, please install pciutils! PCIDevice *hi_scan_pci(void) { FILE *proc_pci; gchar buffer[256], *buf; gboolean next_is_name = FALSE; gint n=0; PCIDevice *pci_dev, *pci; struct stat st; g_print("Scanning PCI devices... "); pci = NULL; if(stat("/proc/pci", &st)) return NULL; proc_pci = fopen("/proc/pci", "r"); while(fgets(buffer, 256, proc_pci)){ buf = g_strstrip(buffer); if(next_is_name == TRUE) { gpointer start, end; start = buf; walk_until(':'); end = buf+1; *buf=0; buf = start; pci_dev->category = g_strdup(buf); buf = end; buf[strlen(buf)-1]=0; pci_dev->name = g_strdup(buf); next_is_name = FALSE; } else if(!strncmp(buf, "IRQ", 3)){ gint irq; sscanf(buf, "IRQ %d", &irq); pci_dev->irq = irq; } else if(!strncmp(buf, "Prefetchable 32 bit", 19) || !strncmp(buf, "Non-prefetchable 32 bit", 23)){ gulong mem_st, mem_end; if(*buf == 'N') buf+=4; buf++; sscanf(buf, "refetchable 32 bit memory at %lx [%lx]", &mem_st, &mem_end); pci_dev->memory+=(mem_end-mem_st)/1024; } else if(!strncmp(buf, "I/O", 3)){ guint io_addr, io_addr_end; sscanf(buf, "I/O at %x [%x]", &io_addr, &io_addr_end); pci_dev->io_addr = io_addr; pci_dev->io_addr_end = io_addr_end; } else if(!strncmp(buf, "Bus", 3)){ gint bus, device, function; pci_dev = g_new0(PCIDevice, 1); pci_dev->next = pci; pci = pci_dev; sscanf(buf, "Bus %d, device %d, function %d:", &bus, &device, &function); pci_dev->bus = bus; pci_dev->device = device; pci_dev->function = function; next_is_name = TRUE; n++; } } fclose(proc_pci); g_print ("%d devices found\n", n); return pci; } #endif