1*c2e0c6b5SAndroid Build Coastguard Worker /*
2*c2e0c6b5SAndroid Build Coastguard Worker * The PCI Library -- User Access
3*c2e0c6b5SAndroid Build Coastguard Worker *
4*c2e0c6b5SAndroid Build Coastguard Worker * Copyright (c) 1997--2022 Martin Mares <[email protected]>
5*c2e0c6b5SAndroid Build Coastguard Worker *
6*c2e0c6b5SAndroid Build Coastguard Worker * Can be freely distributed and used under the terms of the GNU GPL v2+.
7*c2e0c6b5SAndroid Build Coastguard Worker *
8*c2e0c6b5SAndroid Build Coastguard Worker * SPDX-License-Identifier: GPL-2.0-or-later
9*c2e0c6b5SAndroid Build Coastguard Worker */
10*c2e0c6b5SAndroid Build Coastguard Worker
11*c2e0c6b5SAndroid Build Coastguard Worker #include <stdio.h>
12*c2e0c6b5SAndroid Build Coastguard Worker #include <stdlib.h>
13*c2e0c6b5SAndroid Build Coastguard Worker #include <stdarg.h>
14*c2e0c6b5SAndroid Build Coastguard Worker #include <string.h>
15*c2e0c6b5SAndroid Build Coastguard Worker
16*c2e0c6b5SAndroid Build Coastguard Worker #include "internal.h"
17*c2e0c6b5SAndroid Build Coastguard Worker
18*c2e0c6b5SAndroid Build Coastguard Worker void
pci_scan_bus(struct pci_access * a)19*c2e0c6b5SAndroid Build Coastguard Worker pci_scan_bus(struct pci_access *a)
20*c2e0c6b5SAndroid Build Coastguard Worker {
21*c2e0c6b5SAndroid Build Coastguard Worker a->methods->scan(a);
22*c2e0c6b5SAndroid Build Coastguard Worker }
23*c2e0c6b5SAndroid Build Coastguard Worker
24*c2e0c6b5SAndroid Build Coastguard Worker struct pci_dev *
pci_alloc_dev(struct pci_access * a)25*c2e0c6b5SAndroid Build Coastguard Worker pci_alloc_dev(struct pci_access *a)
26*c2e0c6b5SAndroid Build Coastguard Worker {
27*c2e0c6b5SAndroid Build Coastguard Worker struct pci_dev *d = pci_malloc(a, sizeof(struct pci_dev));
28*c2e0c6b5SAndroid Build Coastguard Worker
29*c2e0c6b5SAndroid Build Coastguard Worker memset(d, 0, sizeof(*d));
30*c2e0c6b5SAndroid Build Coastguard Worker d->access = a;
31*c2e0c6b5SAndroid Build Coastguard Worker d->methods = a->methods;
32*c2e0c6b5SAndroid Build Coastguard Worker d->hdrtype = -1;
33*c2e0c6b5SAndroid Build Coastguard Worker d->numa_node = -1;
34*c2e0c6b5SAndroid Build Coastguard Worker if (d->methods->init_dev)
35*c2e0c6b5SAndroid Build Coastguard Worker d->methods->init_dev(d);
36*c2e0c6b5SAndroid Build Coastguard Worker return d;
37*c2e0c6b5SAndroid Build Coastguard Worker }
38*c2e0c6b5SAndroid Build Coastguard Worker
39*c2e0c6b5SAndroid Build Coastguard Worker int
pci_link_dev(struct pci_access * a,struct pci_dev * d)40*c2e0c6b5SAndroid Build Coastguard Worker pci_link_dev(struct pci_access *a, struct pci_dev *d)
41*c2e0c6b5SAndroid Build Coastguard Worker {
42*c2e0c6b5SAndroid Build Coastguard Worker d->next = a->devices;
43*c2e0c6b5SAndroid Build Coastguard Worker a->devices = d;
44*c2e0c6b5SAndroid Build Coastguard Worker
45*c2e0c6b5SAndroid Build Coastguard Worker /*
46*c2e0c6b5SAndroid Build Coastguard Worker * Applications compiled with older versions of libpci do not expect
47*c2e0c6b5SAndroid Build Coastguard Worker * 32-bit domain numbers. To keep them working, we keep a 16-bit
48*c2e0c6b5SAndroid Build Coastguard Worker * version of the domain number at the previous location in struct
49*c2e0c6b5SAndroid Build Coastguard Worker * pci_dev. This will keep backward compatibility on systems which
50*c2e0c6b5SAndroid Build Coastguard Worker * don't require large domain numbers.
51*c2e0c6b5SAndroid Build Coastguard Worker */
52*c2e0c6b5SAndroid Build Coastguard Worker if (d->domain > 0xffff)
53*c2e0c6b5SAndroid Build Coastguard Worker d->domain_16 = 0xffff;
54*c2e0c6b5SAndroid Build Coastguard Worker else
55*c2e0c6b5SAndroid Build Coastguard Worker d->domain_16 = d->domain;
56*c2e0c6b5SAndroid Build Coastguard Worker
57*c2e0c6b5SAndroid Build Coastguard Worker return 1;
58*c2e0c6b5SAndroid Build Coastguard Worker }
59*c2e0c6b5SAndroid Build Coastguard Worker
60*c2e0c6b5SAndroid Build Coastguard Worker struct pci_dev *
pci_get_dev(struct pci_access * a,int domain,int bus,int dev,int func)61*c2e0c6b5SAndroid Build Coastguard Worker pci_get_dev(struct pci_access *a, int domain, int bus, int dev, int func)
62*c2e0c6b5SAndroid Build Coastguard Worker {
63*c2e0c6b5SAndroid Build Coastguard Worker struct pci_dev *d = pci_alloc_dev(a);
64*c2e0c6b5SAndroid Build Coastguard Worker
65*c2e0c6b5SAndroid Build Coastguard Worker d->domain = domain;
66*c2e0c6b5SAndroid Build Coastguard Worker d->bus = bus;
67*c2e0c6b5SAndroid Build Coastguard Worker d->dev = dev;
68*c2e0c6b5SAndroid Build Coastguard Worker d->func = func;
69*c2e0c6b5SAndroid Build Coastguard Worker return d;
70*c2e0c6b5SAndroid Build Coastguard Worker }
71*c2e0c6b5SAndroid Build Coastguard Worker
72*c2e0c6b5SAndroid Build Coastguard Worker static void
pci_free_properties(struct pci_dev * d)73*c2e0c6b5SAndroid Build Coastguard Worker pci_free_properties(struct pci_dev *d)
74*c2e0c6b5SAndroid Build Coastguard Worker {
75*c2e0c6b5SAndroid Build Coastguard Worker struct pci_property *p;
76*c2e0c6b5SAndroid Build Coastguard Worker
77*c2e0c6b5SAndroid Build Coastguard Worker while (p = d->properties)
78*c2e0c6b5SAndroid Build Coastguard Worker {
79*c2e0c6b5SAndroid Build Coastguard Worker d->properties = p->next;
80*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(p);
81*c2e0c6b5SAndroid Build Coastguard Worker }
82*c2e0c6b5SAndroid Build Coastguard Worker }
83*c2e0c6b5SAndroid Build Coastguard Worker
pci_free_dev(struct pci_dev * d)84*c2e0c6b5SAndroid Build Coastguard Worker void pci_free_dev(struct pci_dev *d)
85*c2e0c6b5SAndroid Build Coastguard Worker {
86*c2e0c6b5SAndroid Build Coastguard Worker if (d->methods->cleanup_dev)
87*c2e0c6b5SAndroid Build Coastguard Worker d->methods->cleanup_dev(d);
88*c2e0c6b5SAndroid Build Coastguard Worker
89*c2e0c6b5SAndroid Build Coastguard Worker pci_free_caps(d);
90*c2e0c6b5SAndroid Build Coastguard Worker pci_free_properties(d);
91*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(d);
92*c2e0c6b5SAndroid Build Coastguard Worker }
93*c2e0c6b5SAndroid Build Coastguard Worker
94*c2e0c6b5SAndroid Build Coastguard Worker static inline void
pci_read_data(struct pci_dev * d,void * buf,int pos,int len)95*c2e0c6b5SAndroid Build Coastguard Worker pci_read_data(struct pci_dev *d, void *buf, int pos, int len)
96*c2e0c6b5SAndroid Build Coastguard Worker {
97*c2e0c6b5SAndroid Build Coastguard Worker if (pos & (len-1))
98*c2e0c6b5SAndroid Build Coastguard Worker d->access->error("Unaligned read: pos=%02x, len=%d", pos, len);
99*c2e0c6b5SAndroid Build Coastguard Worker if (pos + len <= d->cache_len)
100*c2e0c6b5SAndroid Build Coastguard Worker memcpy(buf, d->cache + pos, len);
101*c2e0c6b5SAndroid Build Coastguard Worker else if (!d->methods->read(d, pos, buf, len))
102*c2e0c6b5SAndroid Build Coastguard Worker memset(buf, 0xff, len);
103*c2e0c6b5SAndroid Build Coastguard Worker }
104*c2e0c6b5SAndroid Build Coastguard Worker
105*c2e0c6b5SAndroid Build Coastguard Worker byte
pci_read_byte(struct pci_dev * d,int pos)106*c2e0c6b5SAndroid Build Coastguard Worker pci_read_byte(struct pci_dev *d, int pos)
107*c2e0c6b5SAndroid Build Coastguard Worker {
108*c2e0c6b5SAndroid Build Coastguard Worker byte buf;
109*c2e0c6b5SAndroid Build Coastguard Worker pci_read_data(d, &buf, pos, 1);
110*c2e0c6b5SAndroid Build Coastguard Worker return buf;
111*c2e0c6b5SAndroid Build Coastguard Worker }
112*c2e0c6b5SAndroid Build Coastguard Worker
113*c2e0c6b5SAndroid Build Coastguard Worker word
pci_read_word(struct pci_dev * d,int pos)114*c2e0c6b5SAndroid Build Coastguard Worker pci_read_word(struct pci_dev *d, int pos)
115*c2e0c6b5SAndroid Build Coastguard Worker {
116*c2e0c6b5SAndroid Build Coastguard Worker word buf;
117*c2e0c6b5SAndroid Build Coastguard Worker pci_read_data(d, &buf, pos, 2);
118*c2e0c6b5SAndroid Build Coastguard Worker return le16_to_cpu(buf);
119*c2e0c6b5SAndroid Build Coastguard Worker }
120*c2e0c6b5SAndroid Build Coastguard Worker
121*c2e0c6b5SAndroid Build Coastguard Worker u32
pci_read_long(struct pci_dev * d,int pos)122*c2e0c6b5SAndroid Build Coastguard Worker pci_read_long(struct pci_dev *d, int pos)
123*c2e0c6b5SAndroid Build Coastguard Worker {
124*c2e0c6b5SAndroid Build Coastguard Worker u32 buf;
125*c2e0c6b5SAndroid Build Coastguard Worker pci_read_data(d, &buf, pos, 4);
126*c2e0c6b5SAndroid Build Coastguard Worker return le32_to_cpu(buf);
127*c2e0c6b5SAndroid Build Coastguard Worker }
128*c2e0c6b5SAndroid Build Coastguard Worker
129*c2e0c6b5SAndroid Build Coastguard Worker int
pci_read_block(struct pci_dev * d,int pos,byte * buf,int len)130*c2e0c6b5SAndroid Build Coastguard Worker pci_read_block(struct pci_dev *d, int pos, byte *buf, int len)
131*c2e0c6b5SAndroid Build Coastguard Worker {
132*c2e0c6b5SAndroid Build Coastguard Worker return d->methods->read(d, pos, buf, len);
133*c2e0c6b5SAndroid Build Coastguard Worker }
134*c2e0c6b5SAndroid Build Coastguard Worker
135*c2e0c6b5SAndroid Build Coastguard Worker int
pci_read_vpd(struct pci_dev * d,int pos,byte * buf,int len)136*c2e0c6b5SAndroid Build Coastguard Worker pci_read_vpd(struct pci_dev *d, int pos, byte *buf, int len)
137*c2e0c6b5SAndroid Build Coastguard Worker {
138*c2e0c6b5SAndroid Build Coastguard Worker return d->methods->read_vpd ? d->methods->read_vpd(d, pos, buf, len) : 0;
139*c2e0c6b5SAndroid Build Coastguard Worker }
140*c2e0c6b5SAndroid Build Coastguard Worker
141*c2e0c6b5SAndroid Build Coastguard Worker static inline int
pci_write_data(struct pci_dev * d,void * buf,int pos,int len)142*c2e0c6b5SAndroid Build Coastguard Worker pci_write_data(struct pci_dev *d, void *buf, int pos, int len)
143*c2e0c6b5SAndroid Build Coastguard Worker {
144*c2e0c6b5SAndroid Build Coastguard Worker if (pos & (len-1))
145*c2e0c6b5SAndroid Build Coastguard Worker d->access->error("Unaligned write: pos=%02x,len=%d", pos, len);
146*c2e0c6b5SAndroid Build Coastguard Worker if (pos + len <= d->cache_len)
147*c2e0c6b5SAndroid Build Coastguard Worker memcpy(d->cache + pos, buf, len);
148*c2e0c6b5SAndroid Build Coastguard Worker return d->methods->write(d, pos, buf, len);
149*c2e0c6b5SAndroid Build Coastguard Worker }
150*c2e0c6b5SAndroid Build Coastguard Worker
151*c2e0c6b5SAndroid Build Coastguard Worker int
pci_write_byte(struct pci_dev * d,int pos,byte data)152*c2e0c6b5SAndroid Build Coastguard Worker pci_write_byte(struct pci_dev *d, int pos, byte data)
153*c2e0c6b5SAndroid Build Coastguard Worker {
154*c2e0c6b5SAndroid Build Coastguard Worker return pci_write_data(d, &data, pos, 1);
155*c2e0c6b5SAndroid Build Coastguard Worker }
156*c2e0c6b5SAndroid Build Coastguard Worker
157*c2e0c6b5SAndroid Build Coastguard Worker int
pci_write_word(struct pci_dev * d,int pos,word data)158*c2e0c6b5SAndroid Build Coastguard Worker pci_write_word(struct pci_dev *d, int pos, word data)
159*c2e0c6b5SAndroid Build Coastguard Worker {
160*c2e0c6b5SAndroid Build Coastguard Worker word buf = cpu_to_le16(data);
161*c2e0c6b5SAndroid Build Coastguard Worker return pci_write_data(d, &buf, pos, 2);
162*c2e0c6b5SAndroid Build Coastguard Worker }
163*c2e0c6b5SAndroid Build Coastguard Worker
164*c2e0c6b5SAndroid Build Coastguard Worker int
pci_write_long(struct pci_dev * d,int pos,u32 data)165*c2e0c6b5SAndroid Build Coastguard Worker pci_write_long(struct pci_dev *d, int pos, u32 data)
166*c2e0c6b5SAndroid Build Coastguard Worker {
167*c2e0c6b5SAndroid Build Coastguard Worker u32 buf = cpu_to_le32(data);
168*c2e0c6b5SAndroid Build Coastguard Worker return pci_write_data(d, &buf, pos, 4);
169*c2e0c6b5SAndroid Build Coastguard Worker }
170*c2e0c6b5SAndroid Build Coastguard Worker
171*c2e0c6b5SAndroid Build Coastguard Worker int
pci_write_block(struct pci_dev * d,int pos,byte * buf,int len)172*c2e0c6b5SAndroid Build Coastguard Worker pci_write_block(struct pci_dev *d, int pos, byte *buf, int len)
173*c2e0c6b5SAndroid Build Coastguard Worker {
174*c2e0c6b5SAndroid Build Coastguard Worker if (pos < d->cache_len)
175*c2e0c6b5SAndroid Build Coastguard Worker {
176*c2e0c6b5SAndroid Build Coastguard Worker int l = (pos + len >= d->cache_len) ? (d->cache_len - pos) : len;
177*c2e0c6b5SAndroid Build Coastguard Worker memcpy(d->cache + pos, buf, l);
178*c2e0c6b5SAndroid Build Coastguard Worker }
179*c2e0c6b5SAndroid Build Coastguard Worker return d->methods->write(d, pos, buf, len);
180*c2e0c6b5SAndroid Build Coastguard Worker }
181*c2e0c6b5SAndroid Build Coastguard Worker
182*c2e0c6b5SAndroid Build Coastguard Worker static void
pci_reset_properties(struct pci_dev * d)183*c2e0c6b5SAndroid Build Coastguard Worker pci_reset_properties(struct pci_dev *d)
184*c2e0c6b5SAndroid Build Coastguard Worker {
185*c2e0c6b5SAndroid Build Coastguard Worker d->known_fields = 0;
186*c2e0c6b5SAndroid Build Coastguard Worker d->phy_slot = NULL;
187*c2e0c6b5SAndroid Build Coastguard Worker d->module_alias = NULL;
188*c2e0c6b5SAndroid Build Coastguard Worker d->label = NULL;
189*c2e0c6b5SAndroid Build Coastguard Worker pci_free_caps(d);
190*c2e0c6b5SAndroid Build Coastguard Worker pci_free_properties(d);
191*c2e0c6b5SAndroid Build Coastguard Worker }
192*c2e0c6b5SAndroid Build Coastguard Worker
193*c2e0c6b5SAndroid Build Coastguard Worker int
pci_fill_info_v313(struct pci_dev * d,int flags)194*c2e0c6b5SAndroid Build Coastguard Worker pci_fill_info_v313(struct pci_dev *d, int flags)
195*c2e0c6b5SAndroid Build Coastguard Worker {
196*c2e0c6b5SAndroid Build Coastguard Worker unsigned int uflags = flags;
197*c2e0c6b5SAndroid Build Coastguard Worker if (uflags & PCI_FILL_RESCAN)
198*c2e0c6b5SAndroid Build Coastguard Worker {
199*c2e0c6b5SAndroid Build Coastguard Worker uflags &= ~PCI_FILL_RESCAN;
200*c2e0c6b5SAndroid Build Coastguard Worker pci_reset_properties(d);
201*c2e0c6b5SAndroid Build Coastguard Worker }
202*c2e0c6b5SAndroid Build Coastguard Worker if (uflags & ~d->known_fields)
203*c2e0c6b5SAndroid Build Coastguard Worker d->methods->fill_info(d, uflags);
204*c2e0c6b5SAndroid Build Coastguard Worker return d->known_fields;
205*c2e0c6b5SAndroid Build Coastguard Worker }
206*c2e0c6b5SAndroid Build Coastguard Worker
207*c2e0c6b5SAndroid Build Coastguard Worker /* In version 3.1, pci_fill_info got new flags => versioned alias */
208*c2e0c6b5SAndroid Build Coastguard Worker /* In versions 3.2, 3.3, 3.4, 3.5, 3.8 and 3.12, the same has happened */
209*c2e0c6b5SAndroid Build Coastguard Worker STATIC_ALIAS(int pci_fill_info(struct pci_dev *d, int flags), pci_fill_info_v313(d, flags));
210*c2e0c6b5SAndroid Build Coastguard Worker DEFINE_ALIAS(int pci_fill_info_v30(struct pci_dev *d, int flags), pci_fill_info_v313);
211*c2e0c6b5SAndroid Build Coastguard Worker DEFINE_ALIAS(int pci_fill_info_v31(struct pci_dev *d, int flags), pci_fill_info_v313);
212*c2e0c6b5SAndroid Build Coastguard Worker DEFINE_ALIAS(int pci_fill_info_v32(struct pci_dev *d, int flags), pci_fill_info_v313);
213*c2e0c6b5SAndroid Build Coastguard Worker DEFINE_ALIAS(int pci_fill_info_v33(struct pci_dev *d, int flags), pci_fill_info_v313);
214*c2e0c6b5SAndroid Build Coastguard Worker DEFINE_ALIAS(int pci_fill_info_v34(struct pci_dev *d, int flags), pci_fill_info_v313);
215*c2e0c6b5SAndroid Build Coastguard Worker DEFINE_ALIAS(int pci_fill_info_v35(struct pci_dev *d, int flags), pci_fill_info_v313);
216*c2e0c6b5SAndroid Build Coastguard Worker DEFINE_ALIAS(int pci_fill_info_v38(struct pci_dev *d, int flags), pci_fill_info_v313);
217*c2e0c6b5SAndroid Build Coastguard Worker SYMBOL_VERSION(pci_fill_info_v30, pci_fill_info@LIBPCI_3.0);
218*c2e0c6b5SAndroid Build Coastguard Worker SYMBOL_VERSION(pci_fill_info_v31, pci_fill_info@LIBPCI_3.1);
219*c2e0c6b5SAndroid Build Coastguard Worker SYMBOL_VERSION(pci_fill_info_v32, pci_fill_info@LIBPCI_3.2);
220*c2e0c6b5SAndroid Build Coastguard Worker SYMBOL_VERSION(pci_fill_info_v33, pci_fill_info@LIBPCI_3.3);
221*c2e0c6b5SAndroid Build Coastguard Worker SYMBOL_VERSION(pci_fill_info_v34, pci_fill_info@LIBPCI_3.4);
222*c2e0c6b5SAndroid Build Coastguard Worker SYMBOL_VERSION(pci_fill_info_v35, pci_fill_info@LIBPCI_3.5);
223*c2e0c6b5SAndroid Build Coastguard Worker SYMBOL_VERSION(pci_fill_info_v38, pci_fill_info@LIBPCI_3.8);
224*c2e0c6b5SAndroid Build Coastguard Worker SYMBOL_VERSION(pci_fill_info_v313, pci_fill_info@@LIBPCI_3.13);
225*c2e0c6b5SAndroid Build Coastguard Worker
226*c2e0c6b5SAndroid Build Coastguard Worker void
pci_setup_cache(struct pci_dev * d,byte * cache,int len)227*c2e0c6b5SAndroid Build Coastguard Worker pci_setup_cache(struct pci_dev *d, byte *cache, int len)
228*c2e0c6b5SAndroid Build Coastguard Worker {
229*c2e0c6b5SAndroid Build Coastguard Worker d->cache = cache;
230*c2e0c6b5SAndroid Build Coastguard Worker d->cache_len = len;
231*c2e0c6b5SAndroid Build Coastguard Worker }
232*c2e0c6b5SAndroid Build Coastguard Worker
233*c2e0c6b5SAndroid Build Coastguard Worker char *
pci_set_property(struct pci_dev * d,u32 key,char * value)234*c2e0c6b5SAndroid Build Coastguard Worker pci_set_property(struct pci_dev *d, u32 key, char *value)
235*c2e0c6b5SAndroid Build Coastguard Worker {
236*c2e0c6b5SAndroid Build Coastguard Worker struct pci_property *p;
237*c2e0c6b5SAndroid Build Coastguard Worker struct pci_property **pp = &d->properties;
238*c2e0c6b5SAndroid Build Coastguard Worker
239*c2e0c6b5SAndroid Build Coastguard Worker while (p = *pp)
240*c2e0c6b5SAndroid Build Coastguard Worker {
241*c2e0c6b5SAndroid Build Coastguard Worker if (p->key == key)
242*c2e0c6b5SAndroid Build Coastguard Worker {
243*c2e0c6b5SAndroid Build Coastguard Worker *pp = p->next;
244*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(p);
245*c2e0c6b5SAndroid Build Coastguard Worker }
246*c2e0c6b5SAndroid Build Coastguard Worker else
247*c2e0c6b5SAndroid Build Coastguard Worker pp = &p->next;
248*c2e0c6b5SAndroid Build Coastguard Worker }
249*c2e0c6b5SAndroid Build Coastguard Worker
250*c2e0c6b5SAndroid Build Coastguard Worker if (!value)
251*c2e0c6b5SAndroid Build Coastguard Worker return NULL;
252*c2e0c6b5SAndroid Build Coastguard Worker
253*c2e0c6b5SAndroid Build Coastguard Worker p = pci_malloc(d->access, sizeof(*p) + strlen(value));
254*c2e0c6b5SAndroid Build Coastguard Worker *pp = p;
255*c2e0c6b5SAndroid Build Coastguard Worker p->next = NULL;
256*c2e0c6b5SAndroid Build Coastguard Worker p->key = key;
257*c2e0c6b5SAndroid Build Coastguard Worker strcpy(p->value, value);
258*c2e0c6b5SAndroid Build Coastguard Worker
259*c2e0c6b5SAndroid Build Coastguard Worker return p->value;
260*c2e0c6b5SAndroid Build Coastguard Worker }
261*c2e0c6b5SAndroid Build Coastguard Worker
262*c2e0c6b5SAndroid Build Coastguard Worker char *
pci_get_string_property(struct pci_dev * d,u32 prop)263*c2e0c6b5SAndroid Build Coastguard Worker pci_get_string_property(struct pci_dev *d, u32 prop)
264*c2e0c6b5SAndroid Build Coastguard Worker {
265*c2e0c6b5SAndroid Build Coastguard Worker struct pci_property *p;
266*c2e0c6b5SAndroid Build Coastguard Worker
267*c2e0c6b5SAndroid Build Coastguard Worker for (p = d->properties; p; p = p->next)
268*c2e0c6b5SAndroid Build Coastguard Worker if (p->key == prop)
269*c2e0c6b5SAndroid Build Coastguard Worker return p->value;
270*c2e0c6b5SAndroid Build Coastguard Worker
271*c2e0c6b5SAndroid Build Coastguard Worker return NULL;
272*c2e0c6b5SAndroid Build Coastguard Worker }
273