/* * 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 */ #include #include #include #include #include #include "../biostest.h" struct device { char pciid[20]; unsigned long size; }; static GList *sizes; static void read_resource_db(void) { FILE *file; char line[4096]; char *c1,*c2; file = fopen("/usr/share/LFDK/plugins/resourcedb.txt", "r"); if (file==NULL) file = fopen("resourcedb.txt", "r"); if (file==NULL) return; while (!feof(file)) { memset(line, 0, 4096); if (!fgets(line, 4096, file)) break; if (strlen(line)<9) continue; if (line[0]=='#') continue; c1=&line[8]; /* find the first whitespace */ while (*c1!=0 && *c1!=' ' && *c1!='\t') c1++; *c1 = 0; c1++; while (strlen(c1)>0) { struct device *dev; unsigned long value = 0; /* skip whitespace */ while (*c1==0 || *c1==' ' || *c1=='\t') c1++; if (strlen(c1)<1) break; dev = malloc(sizeof(struct device)); if (dev==NULL) break; memset(dev, 0, sizeof(struct device)); strcpy(dev->pciid, line); value = strtoul(c1, &c2, 10); /* weird things get presented as hex */ if (strlen(c2)>0) { if (*c2 == 'K') value = value * 1024; else if (*c2 == 'M') value = value * 1024 * 1024; else if (*c2 == 'G') value = value * 1024 * 1024 * 1024; c2++; } c1=c2; dev->size = value; sizes = g_list_append(sizes, dev); } } fclose(file); } static int matches_db(char *devid, unsigned long size) { GList *item; struct device *dev; int ret = 0; item = g_list_first(sizes); while (item) { dev = (struct device *)item->data; item = g_list_next(item); if (strcmp(devid, dev->pciid)!=0) continue; ret = -1; if (size==dev->size) return 1; } return ret; } void check_resource_size_against_db(void) { char current_device[4096]; char line[4096]; char uri[4095]; char *c; char *lspci_cmd; FILE *file; if (sizes==NULL) read_resource_db(); memset(current_device, 0, 4096); lspci_cmd = get_relative_command ("lspci", " -v -n"); if(!lspci_cmd) { sprintf(line,"echo lspci not found >> %s", LFDK_ERRLOG); system(line); return; } file = popen(lspci_cmd, "r"); while (!feof(file)) { char *c2, *c3; char devid[14]; int maybehex=0; if (fgets(line, 4095, file)==NULL) break; if (line[0] != ' ' && line[0] != '\t') { strcpy(current_device, line); memset(devid,0,14); strncpy(devid, &line[14],10); c2=strchr(current_device, ' '); if (c2) *c2=0; c2=strchr(devid, ' '); if (c2) *c2=0; } c = strstr(line, "[size="); if (c && strstr(line,"Memory")) { uint64_t value; c+=6; c2=strchr(c, ']'); if (c2) *c2 = 0; value = strtoul(c, &c3, 10); /* weird things get presented as hex */ while (strlen(c3)>0) { if (*c3 == 'K') value = value * 1024; else if (*c3 == 'M') value = value * 1024 * 1024; else if (*c3 == 'G') value = value * 1024 * 1024 * 1024; else maybehex = 1; c3++; } if (maybehex) value = strtoul(c, &c3, 16); if (matches_db(devid, value) <0 ) { char output[4096]; current_device[8] = 0; sprintf(uri, "pci://0000:%s", current_device); sprintf(output, "Device %s has a resource size that is not in the database: %lli", current_device, value); report_result("pciresource", FAIL, output, NULL, uri); } } } fclose(file); }