/* * Copyright (C) 2006, Intel Corporation * * This file is part of the Linux-ready Firmware Developer Kit * * This program file is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation;version 2.1 of the License. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program in a file named COPYING; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ /* * This test checks if MaxReadReq is set > 128 for non-internal stuff * A too low value hurts performance */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* main() -- This plugin checks the lspci output for * the maxreadreq of a device. If it is * 128 (considered low), it will report * a warning. * * Parameters * argc & argv * Returns * EXIT_SUCCESS upon success of running this plugin * EXIT_FAILURE upon failure of running this plugin */ int main(int argc, char **argv) { FILE *file; char current_type[512]; char current_device[512]; char *lspci_cmd; struct stat buffer; memset(current_type, 0, 512); memset(current_device, 0, 512); start_test("maxreadreq", "PCI Express MaxReadReq tuning", "This test checks if the firmware has set MaxReadReq to a higher value on non-montherboard devices"); lspci_cmd = get_relative_command ("lspci", " -vvv"); file = popen(lspci_cmd, "r"); if (!file) { report_result("maxreadreq", FAIL, "Cannot execute lspci command", lspci_cmd, NULL); goto finish; } while (!feof(file)) { char line[4096]; int val = 0; char *c; memset(line, 0, 4096); if (fgets(line, 4095, file)==NULL) break; if (line[0]!=' ' && line[0] != '\t' && strlen(line)>8) { if (strlen(line) > 500){ report_result("maxreadreq", WARN, "Too big pci" "string would overflow" "current_device buffer", "Internal plugin, not a firmware" " bug", current_device); break; } sprintf(current_device, "pci://00:%s", line); current_device[16] = 0; strncpy(current_type, line+8, 511); c = strchr(current_type, ':'); if (c) *c=0; } /* chipset devices are exempt from this check */ if (strcmp(current_type, "PCI bridge")==0) continue; if (strcmp(current_type, "Host bridge")==0) continue; if (strcmp(current_type, "System peripheral")==0) continue; c = strstr(line, "MaxReadReq "); if (c) { char buffer[4096]; sprintf(buffer, "MaxReadReq for device %s is low (128)", current_device); c += 11; val = strtoul(c, NULL, 10); if (val == 128) report_result("maxreadreq", WARN, buffer, NULL, current_device); } } pclose(file); finish: finish_test("maxreadreq"); return EXIT_SUCCESS; }