]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - setpci.c
2 * $Id: setpci.c,v 1.1 1998/03/31 21:02:20 mj Exp $
4 * Linux PCI Utilities -- Manipulate PCI Configuration Registers
6 * Copyright (c) 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
8 * Can be freely distributed and used under the terms of the GNU GPL.
19 static int force
; /* Don't complain if no devices match */
20 static int verbose
; /* Verbosity level */
24 byte bus
, devfn
, mark
;
29 static struct device
*first_dev
;
33 struct device
**dev_vector
;
35 unsigned int width
; /* Byte width of the access */
36 int num_values
; /* Number of values to write; <0=read */
37 unsigned int values
[0];
40 static struct op
*first_op
, **last_op
= &first_op
;
43 xmalloc(unsigned int howmuch
)
45 void *p
= malloc(howmuch
);
48 fprintf(stderr
, "setpci: Unable to allocate %d bytes of memory\n", howmuch
);
57 struct device
**last
= &first_dev
;
61 if (!(f
= fopen(PROC_BUS_PCI
"/devices", "r")))
63 perror(PROC_BUS_PCI
"/devices");
66 while (fgets(line
, sizeof(line
), f
))
68 struct device
*d
= xmalloc(sizeof(struct device
));
69 unsigned int dfn
, vend
;
71 sscanf(line
, "%x %x", &dfn
, &vend
);
73 d
->devfn
= dfn
& 0xff;
74 d
->vendid
= vend
>> 16U;
75 d
->devid
= vend
& 0xffff;
84 static struct device
**
85 select_devices(struct pci_filter
*filt
)
87 struct device
*z
, **a
, **b
;
90 for(z
=first_dev
; z
; z
=z
->next
)
91 if (z
->mark
= filter_match(filt
, z
->bus
, z
->devfn
, z
->vendid
, z
->devid
))
93 a
= b
= xmalloc(sizeof(struct device
*) * cnt
);
94 for(z
=first_dev
; z
; z
=z
->next
)
102 exec_op(struct op
*op
, struct device
*dev
)
104 char *mm
[] = { NULL
, "%02x", "%04x", NULL
, "%08x" };
105 char *m
= mm
[op
->width
];
110 sprintf(name
, PROC_BUS_PCI
"/%02x/%02x.%x", dev
->bus
, PCI_SLOT(dev
->devfn
), PCI_FUNC(dev
->devfn
));
111 dev
->fd
= open(name
, O_RDWR
????
115 printf("%02x.%02x:%x.%c ", dev
->bus
, PCI_SLOT(dev
->devfn
), PCI_FUNC(dev
->devfn
),
117 if (op
->num_values
> 0)
128 execute(struct op
*op
)
130 struct device
**vec
= NULL
;
131 struct device
**pdev
, *dev
;
136 pdev
= vec
= op
->dev_vector
;
137 while (dev
= *pdev
++)
138 for(oops
=op
; oops
&& oops
->dev_vector
== vec
; oops
=oops
->next
)
140 while (op
&& op
->dev_vector
== vec
)
145 static void usage(void) __attribute__((noreturn
));
151 "Usage: setpci [-f] [-v] (<device>+ <reg>[=<values>]*)*\n\
152 <device>: -s [[<bus>]:][<slot>][.[<func>]]\n\
153 \t| -d [<vendor>]:[<device>]\n\
154 <reg>: <number>[.(B|W|L)]\n\
155 <values>: <value>[,<value>...]\n\
161 main(int argc
, char **argv
)
163 enum { STATE_INIT
, STATE_GOT_FILTER
, STATE_GOT_OP
} state
= STATE_INIT
;
164 struct pci_filter filter
;
165 struct device
**selected_devices
= NULL
;
169 while (argc
&& argv
[0][0] == '-')
204 unsigned long ll
, lim
;
208 if (!c
[1] || !strchr("sd", c
[1]))
211 d
= (c
[2] == '=') ? c
+3 : c
+2;
220 if (state
!= STATE_GOT_FILTER
)
222 filter_init(&filter
);
223 state
= STATE_GOT_FILTER
;
228 if (d
= filter_parse_slot(&filter
, d
))
230 fprintf(stderr
, "setpci: -s: %s\n", d
);
235 if (d
= filter_parse_id(&filter
, d
))
237 fprintf(stderr
, "setpci: -d: %s\n", d
);
245 else if (state
== STATE_INIT
)
249 if (state
== STATE_GOT_FILTER
)
250 selected_devices
= select_devices(&filter
);
251 if (!selected_devices
[0] && !force
)
252 fprintf(stderr
, "setpci: Warning: No devices selected for `%s'.\n", c
);
253 state
= STATE_GOT_OP
;
258 for(e
=d
, n
=1; *e
; e
++)
261 op
= xmalloc(sizeof(struct op
) + n
*sizeof(unsigned int));
266 op
= xmalloc(sizeof(struct op
));
268 op
->dev_vector
= selected_devices
;
279 op
->width
= 1; break;
281 op
->width
= 2; break;
283 op
->width
= 4; break;
290 ll
= strtol(c
, &f
, 16);
291 if (ll
> 0x100 || ll
+ op
->width
*n
> 0x100)
293 fprintf(stderr
, "setpci: Register number out of range!\n");
301 ll
= strtoul(d
, &f
, 16);
302 lim
= (2 << ((op
->width
<< 3) - 1)) - 1;
304 (ll
> lim
&& ll
< ~0UL - lim
))
316 if (state
== STATE_INIT
)