2
* The PCI Library -- Generic Direct Access Functions
4
* Copyright (c) 1997--2000 Martin Mares <mj@ucw.cz>
6
* May 8, 2006 - Modified and ported to HelenOS by Jakub Jermar.
8
* Can be freely distributed and used under the terms of the GNU GPL.
15
void pci_generic_scan_bus(struct pci_access *a, byte * busmap, int bus)
20
a->debug("Scanning bus %02x for devices...\n", bus);
22
a->warning("Bus %02x seen twice (firmware bug). Ignored.",
29
for (dev = 0; dev < 32; dev++) {
32
for (t->func = 0; !t->func || (multi && t->func < 8);
34
u32 vd = pci_read_long(t, PCI_VENDOR_ID);
37
if (!vd || vd == 0xffffffff)
39
ht = pci_read_byte(t, PCI_HEADER_TYPE);
47
d->vendor_id = vd & 0xffff;
48
d->device_id = vd >> 16U;
49
d->known_fields = PCI_FILL_IDENT;
53
case PCI_HEADER_TYPE_NORMAL:
55
case PCI_HEADER_TYPE_BRIDGE:
56
case PCI_HEADER_TYPE_CARDBUS:
57
pci_generic_scan_bus(a, busmap,
63
("Device %04x:%02x:%02x.%d has unknown header type %02x.\n",
64
d->domain, d->bus, d->dev, d->func,
72
void pci_generic_scan(struct pci_access *a)
76
bzero(busmap, sizeof(busmap));
77
pci_generic_scan_bus(a, busmap, 0);
80
int pci_generic_fill_info(struct pci_dev *d, int flags)
82
struct pci_access *a = d->access;
84
if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE))
86
d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
87
if (flags & PCI_FILL_IDENT) {
88
d->vendor_id = pci_read_word(d, PCI_VENDOR_ID);
89
d->device_id = pci_read_word(d, PCI_DEVICE_ID);
91
if (flags & PCI_FILL_IRQ)
92
d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE);
93
if (flags & PCI_FILL_BASES) {
95
bzero(d->base_addr, sizeof(d->base_addr));
97
case PCI_HEADER_TYPE_NORMAL:
100
case PCI_HEADER_TYPE_BRIDGE:
103
case PCI_HEADER_TYPE_CARDBUS:
108
for (i = 0; i < cnt; i++) {
109
u32 x = pci_read_long(d, PCI_BASE_ADDRESS_0 + i * 4);
110
if (!x || x == (u32) ~ 0)
112
if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
115
if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64)
117
else if (i >= cnt - 1)
118
a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.",
122
u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i) * 4);
123
#ifdef PCI_HAVE_64BIT_ADDRESS
124
d->base_addr[i - 1] = x | (((pciaddr_t) y) << 32);
127
a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.",
133
d->base_addr[i - 1] = x;
140
if (flags & PCI_FILL_ROM_BASE) {
142
d->rom_base_addr = 0;
143
switch (d->hdrtype) {
144
case PCI_HEADER_TYPE_NORMAL:
145
reg = PCI_ROM_ADDRESS;
147
case PCI_HEADER_TYPE_BRIDGE:
148
reg = PCI_ROM_ADDRESS1;
152
u32 u = pci_read_long(d, reg);
154
d->rom_base_addr = u;
157
return flags & ~PCI_FILL_SIZES;
161
pci_generic_block_op(struct pci_dev *d, int pos, byte * buf, int len,
162
int (*r) (struct pci_dev * d, int pos, byte * buf,
165
if ((pos & 1) && len >= 1) {
166
if (!r(d, pos, buf, 1))
172
if ((pos & 3) && len >= 2) {
173
if (!r(d, pos, buf, 2))
180
if (!r(d, pos, buf, 4))
187
if (!r(d, pos, buf, 2))
193
if (len && !r(d, pos, buf, 1))
198
int pci_generic_block_read(struct pci_dev *d, int pos, byte * buf, int len)
200
return pci_generic_block_op(d, pos, buf, len, d->access->methods->read);
203
int pci_generic_block_write(struct pci_dev *d, int pos, byte * buf, int len)
205
return pci_generic_block_op(d, pos, buf, len, d->access->methods->write);