1727ce158SMartin Mares /*
24284af58SMartin Mares * The PCI Utilities -- Common Functions
3727ce158SMartin Mares *
4d1d7d88aSMartin Mares * Copyright (c) 1997--2016 Martin Mares <[email protected]>
5727ce158SMartin Mares *
6*61829219SMartin Mares * Can be freely distributed and used under the terms of the GNU GPL v2+.
7*61829219SMartin Mares *
8*61829219SMartin Mares * SPDX-License-Identifier: GPL-2.0-or-later
9727ce158SMartin Mares */
10727ce158SMartin Mares
11727ce158SMartin Mares #include <stdio.h>
12727ce158SMartin Mares #include <string.h>
13727ce158SMartin Mares #include <stdlib.h>
14727ce158SMartin Mares #include <stdarg.h>
15727ce158SMartin Mares
16727ce158SMartin Mares #include "pciutils.h"
17727ce158SMartin Mares
1891e37a49SMartin Mares void NONRET
die(char * msg,...)19727ce158SMartin Mares die(char *msg, ...)
20727ce158SMartin Mares {
21727ce158SMartin Mares va_list args;
22727ce158SMartin Mares
23727ce158SMartin Mares va_start(args, msg);
2481afa98cSMartin Mares fprintf(stderr, "%s: ", program_name);
25727ce158SMartin Mares vfprintf(stderr, msg, args);
26727ce158SMartin Mares fputc('\n', stderr);
27727ce158SMartin Mares exit(1);
28727ce158SMartin Mares }
29727ce158SMartin Mares
30727ce158SMartin Mares void *
xmalloc(size_t howmuch)31d1d7d88aSMartin Mares xmalloc(size_t howmuch)
32727ce158SMartin Mares {
33727ce158SMartin Mares void *p = malloc(howmuch);
34727ce158SMartin Mares if (!p)
35d1d7d88aSMartin Mares die("Unable to allocate %d bytes of memory", (int) howmuch);
36727ce158SMartin Mares return p;
37727ce158SMartin Mares }
38727ce158SMartin Mares
39ec25b52dSMartin Mares void *
xrealloc(void * ptr,size_t howmuch)40d1d7d88aSMartin Mares xrealloc(void *ptr, size_t howmuch)
41ec25b52dSMartin Mares {
42ec25b52dSMartin Mares void *p = realloc(ptr, howmuch);
43ec25b52dSMartin Mares if (!p)
44d1d7d88aSMartin Mares die("Unable to allocate %d bytes of memory", (int) howmuch);
45ec25b52dSMartin Mares return p;
46ec25b52dSMartin Mares }
47ec25b52dSMartin Mares
48d3f768e2SMartin Mares char *
xstrdup(const char * str)49d1d7d88aSMartin Mares xstrdup(const char *str)
50d3f768e2SMartin Mares {
51d3f768e2SMartin Mares int len = strlen(str) + 1;
52d3f768e2SMartin Mares char *copy = xmalloc(len);
53d3f768e2SMartin Mares memcpy(copy, str, len);
54d3f768e2SMartin Mares return copy;
55d3f768e2SMartin Mares }
56d3f768e2SMartin Mares
57553d12c8SMartin Mares static void
set_pci_method(struct pci_access * pacc,char * arg)58a0407443SMartin Mares set_pci_method(struct pci_access *pacc, char *arg)
59a0407443SMartin Mares {
60a0407443SMartin Mares char *name;
61a0407443SMartin Mares int i;
62a0407443SMartin Mares
63a0407443SMartin Mares if (!strcmp(arg, "help"))
64a0407443SMartin Mares {
65a0407443SMartin Mares printf("Known PCI access methods:\n\n");
66a0407443SMartin Mares for (i=0; name = pci_get_method_name(i); i++)
67a0407443SMartin Mares if (name[0])
68a0407443SMartin Mares printf("%s\n", name);
69a0407443SMartin Mares exit(0);
70a0407443SMartin Mares }
71a0407443SMartin Mares else
72a0407443SMartin Mares {
73a0407443SMartin Mares i = pci_lookup_method(arg);
74a0407443SMartin Mares if (i < 0)
75a0407443SMartin Mares die("No such PCI access method: %s (see `-A help' for a list)", arg);
76a0407443SMartin Mares pacc->method = i;
77a0407443SMartin Mares }
78a0407443SMartin Mares }
79a0407443SMartin Mares
80a0407443SMartin Mares static void
set_pci_option(struct pci_access * pacc,char * arg)81553d12c8SMartin Mares set_pci_option(struct pci_access *pacc, char *arg)
82553d12c8SMartin Mares {
83553d12c8SMartin Mares if (!strcmp(arg, "help"))
84553d12c8SMartin Mares {
85553d12c8SMartin Mares struct pci_param *p;
86553d12c8SMartin Mares printf("Known PCI access parameters:\n\n");
87553d12c8SMartin Mares for (p=NULL; p=pci_walk_params(pacc, p);)
88553d12c8SMartin Mares printf("%-20s %s (%s)\n", p->param, p->help, p->value);
89553d12c8SMartin Mares exit(0);
90553d12c8SMartin Mares }
91553d12c8SMartin Mares else
92553d12c8SMartin Mares {
93553d12c8SMartin Mares char *sep = strchr(arg, '=');
94553d12c8SMartin Mares if (!sep)
95553d12c8SMartin Mares die("Invalid PCI access parameter syntax: %s", arg);
96553d12c8SMartin Mares *sep++ = 0;
97553d12c8SMartin Mares if (pci_set_param(pacc, arg, sep) < 0)
98a0407443SMartin Mares die("Unrecognized PCI access parameter: %s (see `-O help' for a list)", arg);
99553d12c8SMartin Mares }
100553d12c8SMartin Mares }
101553d12c8SMartin Mares
102727ce158SMartin Mares int
parse_generic_option(int i,struct pci_access * pacc,char * arg)103af34f014SMartin Mares parse_generic_option(int i, struct pci_access *pacc, char *arg)
104727ce158SMartin Mares {
105727ce158SMartin Mares switch (i)
106727ce158SMartin Mares {
107489233b4SMartin Mares #ifdef PCI_HAVE_PM_INTEL_CONF
108727ce158SMartin Mares case 'H':
109af34f014SMartin Mares if (!strcmp(arg, "1"))
110727ce158SMartin Mares pacc->method = PCI_ACCESS_I386_TYPE1;
111af34f014SMartin Mares else if (!strcmp(arg, "2"))
112727ce158SMartin Mares pacc->method = PCI_ACCESS_I386_TYPE2;
113727ce158SMartin Mares else
114af34f014SMartin Mares die("Unknown hardware configuration type %s", arg);
115727ce158SMartin Mares break;
116727ce158SMartin Mares #endif
117489233b4SMartin Mares #ifdef PCI_HAVE_PM_DUMP
118727ce158SMartin Mares case 'F':
119af34f014SMartin Mares pci_set_param(pacc, "dump.name", arg);
120727ce158SMartin Mares pacc->method = PCI_ACCESS_DUMP;
121727ce158SMartin Mares break;
122727ce158SMartin Mares #endif
123a0407443SMartin Mares case 'A':
124af34f014SMartin Mares set_pci_method(pacc, arg);
125a0407443SMartin Mares break;
126727ce158SMartin Mares case 'G':
127727ce158SMartin Mares pacc->debugging++;
128727ce158SMartin Mares break;
129553d12c8SMartin Mares case 'O':
130af34f014SMartin Mares set_pci_option(pacc, arg);
131553d12c8SMartin Mares break;
132727ce158SMartin Mares default:
133727ce158SMartin Mares return 0;
134727ce158SMartin Mares }
135727ce158SMartin Mares return 1;
136727ce158SMartin Mares }
137