]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - lib/caps.c
2378591fb739ed25d4b96449fef0b82331218c64
2 * The PCI Library -- Capabilities
4 * Copyright (c) 2008 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
14 pci_add_cap(struct pci_dev
*d
, unsigned int addr
, unsigned int id
, unsigned int type
)
16 struct pci_cap
*cap
= pci_malloc(d
->access
, sizeof(*cap
));
18 cap
->next
= d
->first_cap
;
23 d
->access
->debug("%04x:%02x:%02x.%d: Found capability %04x of type %d at %04x\n",
24 d
->domain
, d
->bus
, d
->dev
, d
->func
, id
, type
, addr
);
28 pci_scan_trad_caps(struct pci_dev
*d
)
30 word status
= pci_read_word(d
, PCI_STATUS
);
34 if (!(status
& PCI_STATUS_CAP_LIST
))
37 memset(been_there
, 0, 256);
38 where
= pci_read_byte(d
, PCI_CAPABILITY_LIST
) & ~3;
41 byte id
= pci_read_byte(d
, where
+ PCI_CAP_LIST_ID
);
42 byte next
= pci_read_byte(d
, where
+ PCI_CAP_LIST_NEXT
) & ~3;
43 if (been_there
[where
]++)
47 pci_add_cap(d
, where
, id
, PCI_CAP_NORMAL
);
53 pci_scan_ext_caps(struct pci_dev
*d
)
55 byte been_there
[0x1000];
58 if (!pci_find_cap(d
, PCI_CAP_ID_EXP
, PCI_CAP_NORMAL
))
61 memset(been_there
, 0, 0x1000);
67 header
= pci_read_long(d
, where
);
68 if (!header
|| header
== 0xffffffff)
71 if (been_there
[where
]++)
73 pci_add_cap(d
, where
, id
, PCI_CAP_EXTENDED
);
74 where
= (header
>> 20) & ~3;
80 pci_scan_caps(struct pci_dev
*d
, unsigned int want_fields
)
82 if ((want_fields
& PCI_FILL_EXT_CAPS
) && !(d
->known_fields
& PCI_FILL_CAPS
))
83 want_fields
|= PCI_FILL_CAPS
;
85 if (want_fields
& PCI_FILL_CAPS
)
86 pci_scan_trad_caps(d
);
87 if (want_fields
& PCI_FILL_EXT_CAPS
)
93 pci_free_caps(struct pci_dev
*d
)
97 while (cap
= d
->first_cap
)
99 d
->first_cap
= cap
->next
;
105 pci_find_cap(struct pci_dev
*d
, unsigned int id
, unsigned int type
)
109 pci_fill_info_v32(d
, ((type
== PCI_CAP_NORMAL
) ? PCI_FILL_CAPS
: PCI_FILL_EXT_CAPS
));
110 for (c
=d
->first_cap
; c
; c
=c
->next
)
111 if (c
->type
== type
&& c
->id
== id
)