/uspace/trunk/pci/libpci/i386-ports.c |
---|
51,13 → 51,11 |
return val; |
} |
static void |
conf12_init(struct pci_access *a) |
static void conf12_init(struct pci_access *a) |
{ |
} |
static void |
conf12_cleanup(struct pci_access *a UNUSED) |
static void conf12_cleanup(struct pci_access *a UNUSED) |
{ |
} |
72,8 → 70,7 |
* chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. |
*/ |
static int |
intel_sanity_check(struct pci_access *a, struct pci_methods *m) |
static int intel_sanity_check(struct pci_access *a, struct pci_methods *m) |
{ |
struct pci_dev d; |
80,15 → 77,19 |
a->debug("...sanity check"); |
d.bus = 0; |
d.func = 0; |
for(d.dev = 0; d.dev < 32; d.dev++) |
{ |
for (d.dev = 0; d.dev < 32; d.dev++) { |
u16 class, vendor; |
if (m->read(&d, PCI_CLASS_DEVICE, (byte *) &class, sizeof(class)) && |
(class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST) || class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)) || |
m->read(&d, PCI_VENDOR_ID, (byte *) &vendor, sizeof(vendor)) && |
(vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL) || vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ))) |
{ |
a->debug("...outside the Asylum at 0/%02x/0", d.dev); |
if (m-> |
read(&d, PCI_CLASS_DEVICE, (byte *) & class, |
sizeof(class)) |
&& (class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST) |
|| class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)) |
|| m->read(&d, PCI_VENDOR_ID, (byte *) & vendor, |
sizeof(vendor)) |
&& (vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL) |
|| vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ))) { |
a->debug("...outside the Asylum at 0/%02x/0", |
d.dev); |
return 1; |
} |
} |
102,8 → 103,7 |
#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3)) |
static int |
conf1_detect(struct pci_access *a) |
static int conf1_detect(struct pci_access *a) |
{ |
unsigned int tmp; |
int res = 0; |
119,8 → 119,7 |
return res; |
} |
static int |
conf1_read(struct pci_dev *d, int pos, byte *buf, int len) |
static int conf1_read(struct pci_dev *d, int pos, byte * buf, int len) |
{ |
int addr = 0xcfc + (pos&3); |
127,10 → 126,10 |
if (pos >= 256) |
return 0; |
outl(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos&~3), 0xcf8); |
outl(0x80000000 | ((d->bus & 0xff) << 16) | |
(PCI_DEVFN(d->dev, d->func) << 8) | (pos & ~3), 0xcf8); |
switch (len) |
{ |
switch (len) { |
case 1: |
buf[0] = inb(addr); |
break; |
146,8 → 145,7 |
return 1; |
} |
static int |
conf1_write(struct pci_dev *d, int pos, byte *buf, int len) |
static int conf1_write(struct pci_dev *d, int pos, byte * buf, int len) |
{ |
int addr = 0xcfc + (pos&3); |
154,10 → 152,10 |
if (pos >= 256) |
return 0; |
outl(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos&~3), 0xcf8); |
outl(0x80000000 | ((d->bus & 0xff) << 16) | |
(PCI_DEVFN(d->dev, d->func) << 8) | (pos & ~3), 0xcf8); |
switch (len) |
{ |
switch (len) { |
case 1: |
outb(buf[0], addr); |
break; |
177,8 → 175,7 |
* Configuration type 2. Obsolete and brain-damaged, but existing. |
*/ |
static int |
conf2_detect(struct pci_access *a) |
static int conf2_detect(struct pci_access *a) |
{ |
/* This is ugly and tends to produce false positives. Beware. */ |
191,8 → 188,7 |
return 0; |
} |
static int |
conf2_read(struct pci_dev *d, int pos, byte *buf, int len) |
static int conf2_read(struct pci_dev *d, int pos, byte * buf, int len) |
{ |
int addr = 0xc000 | (d->dev << 8) | pos; |
204,8 → 200,7 |
return 0; |
outb((d->func << 1) | 0xf0, 0xcf8); |
outb(d->bus, 0xcfa); |
switch (len) |
{ |
switch (len) { |
case 1: |
buf[0] = inb(addr); |
break; |
223,8 → 218,7 |
return 1; |
} |
static int |
conf2_write(struct pci_dev *d, int pos, byte *buf, int len) |
static int conf2_write(struct pci_dev *d, int pos, byte * buf, int len) |
{ |
int addr = 0xc000 | (d->dev << 8) | pos; |
232,11 → 226,11 |
return 0; |
if (d->dev >= 16) |
d->access->error("conf2_write: only first 16 devices exist."); |
d->access-> |
error("conf2_write: only first 16 devices exist."); |
outb((d->func << 1) | 0xf0, 0xcf8); |
outb(d->bus, 0xcfa); |
switch (len) |
{ |
switch (len) { |
case 1: |
outb(buf[0], addr); |
break; |
/uspace/trunk/pci/libpci/pci.h |
---|
145,7 → 145,8 |
* PROGIF (classID, progif) -> programming interface |
*/ |
char *pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, ...); |
char *pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, |
...); |
int pci_load_name_list(struct pci_access *a); /* Called automatically by pci_lookup_*() when needed; returns success */ |
void pci_free_name_list(struct pci_access *a); /* Called automatically by pci_cleanup() */ |
/uspace/trunk/pci/libpci/access.c |
---|
20,8 → 20,7 |
&pm_intel_conf2, |
}; |
struct pci_access * |
pci_alloc(void) |
struct pci_access *pci_alloc(void) |
{ |
struct pci_access *a = malloc(sizeof(struct pci_access)); |
int i; |
33,25 → 32,23 |
return a; |
} |
void * |
pci_malloc(struct pci_access *a, int size) |
void *pci_malloc(struct pci_access *a, int size) |
{ |
void *x = malloc(size); |
if (!x) |
a->error("Out of memory (allocation of %d bytes failed)", size); |
a->error("Out of memory (allocation of %d bytes failed)", |
size); |
return x; |
} |
void |
pci_mfree(void *x) |
void pci_mfree(void *x) |
{ |
if (x) |
free(x); |
} |
static void |
pci_generic_error(char *msg, ...) |
static void pci_generic_error(char *msg, ...) |
{ |
va_list args; |
62,8 → 59,7 |
exit(1); |
} |
static void |
pci_generic_warn(char *msg, ...) |
static void pci_generic_warn(char *msg, ...) |
{ |
va_list args; |
73,8 → 69,7 |
putchar('\n'); |
} |
static void |
pci_generic_debug(char *msg, ...) |
static void pci_generic_debug(char *msg, ...) |
{ |
va_list args; |
83,13 → 78,11 |
va_end(args); |
} |
static void |
pci_null_debug(char *msg UNUSED, ...) |
static void pci_null_debug(char *msg UNUSED, ...) |
{ |
} |
void |
pci_init(struct pci_access *a) |
void pci_init(struct pci_access *a) |
{ |
if (!a->error) |
a->error = pci_generic_error; |
100,21 → 93,16 |
if (!a->debugging) |
a->debug = pci_null_debug; |
if (a->method) |
{ |
if (a->method) { |
if (a->method >= PCI_ACCESS_MAX || !pci_methods[a->method]) |
a->error("This access method is not supported."); |
a->methods = pci_methods[a->method]; |
} |
else |
{ |
} else { |
unsigned int i; |
for(i=0; i<PCI_ACCESS_MAX; i++) |
if (pci_methods[i]) |
{ |
if (pci_methods[i]) { |
a->debug("Trying method %d...", i); |
if (pci_methods[i]->detect(a)) |
{ |
if (pci_methods[i]->detect(a)) { |
a->debug("...OK\n"); |
a->methods = pci_methods[i]; |
a->method = i; |
129,13 → 117,11 |
a->methods->init(a); |
} |
void |
pci_cleanup(struct pci_access *a) |
void pci_cleanup(struct pci_access *a) |
{ |
struct pci_dev *d, *e; |
for(d=a->devices; d; d=e) |
{ |
for (d = a->devices; d; d = e) { |
e = d->next; |
pci_free_dev(d); |
} |
145,14 → 131,12 |
pci_mfree(a); |
} |
void |
pci_scan_bus(struct pci_access *a) |
void pci_scan_bus(struct pci_access *a) |
{ |
a->methods->scan(a); |
} |
struct pci_dev * |
pci_alloc_dev(struct pci_access *a) |
struct pci_dev *pci_alloc_dev(struct pci_access *a) |
{ |
struct pci_dev *d = pci_malloc(a, sizeof(struct pci_dev)); |
165,8 → 149,7 |
return d; |
} |
int |
pci_link_dev(struct pci_access *a, struct pci_dev *d) |
int pci_link_dev(struct pci_access *a, struct pci_dev *d) |
{ |
d->next = a->devices; |
a->devices = d; |
174,8 → 157,8 |
return 1; |
} |
struct pci_dev * |
pci_get_dev(struct pci_access *a, int domain, int bus, int dev, int func) |
struct pci_dev *pci_get_dev(struct pci_access *a, int domain, int bus, |
int dev, int func) |
{ |
struct pci_dev *d = pci_alloc_dev(a); |
197,7 → 180,8 |
pci_read_data(struct pci_dev *d, void *buf, int pos, int len) |
{ |
if (pos & (len-1)) |
d->access->error("Unaligned read: pos=%02x, len=%d", pos, len); |
d->access->error("Unaligned read: pos=%02x, len=%d", pos, |
len); |
if (pos + len <= d->cache_len) |
memcpy(buf, d->cache + pos, len); |
else if (!d->methods->read(d, pos, buf, len)) |
204,8 → 188,7 |
memset(buf, 0xff, len); |
} |
byte |
pci_read_byte(struct pci_dev *d, int pos) |
byte pci_read_byte(struct pci_dev *d, int pos) |
{ |
byte buf; |
pci_read_data(d, &buf, pos, 1); |
212,8 → 195,7 |
return buf; |
} |
word |
pci_read_word(struct pci_dev *d, int pos) |
word pci_read_word(struct pci_dev * d, int pos) |
{ |
word buf; |
pci_read_data(d, &buf, pos, 2); |
220,8 → 202,7 |
return le16_to_cpu(buf); |
} |
u32 |
pci_read_long(struct pci_dev *d, int pos) |
u32 pci_read_long(struct pci_dev * d, int pos) |
{ |
u32 buf; |
pci_read_data(d, &buf, pos, 4); |
228,8 → 209,7 |
return le32_to_cpu(buf); |
} |
int |
pci_read_block(struct pci_dev *d, int pos, byte *buf, int len) |
int pci_read_block(struct pci_dev *d, int pos, byte * buf, int len) |
{ |
return d->methods->read(d, pos, buf, len); |
} |
238,58 → 218,54 |
pci_write_data(struct pci_dev *d, void *buf, int pos, int len) |
{ |
if (pos & (len-1)) |
d->access->error("Unaligned write: pos=%02x,len=%d", pos, len); |
d->access->error("Unaligned write: pos=%02x,len=%d", pos, |
len); |
if (pos + len <= d->cache_len) |
memcpy(d->cache + pos, buf, len); |
return d->methods->write(d, pos, buf, len); |
} |
int |
pci_write_byte(struct pci_dev *d, int pos, byte data) |
int pci_write_byte(struct pci_dev *d, int pos, byte data) |
{ |
return pci_write_data(d, &data, pos, 1); |
} |
int |
pci_write_word(struct pci_dev *d, int pos, word data) |
int pci_write_word(struct pci_dev *d, int pos, word data) |
{ |
word buf = cpu_to_le16(data); |
return pci_write_data(d, &buf, pos, 2); |
} |
int |
pci_write_long(struct pci_dev *d, int pos, u32 data) |
int pci_write_long(struct pci_dev *d, int pos, u32 data) |
{ |
u32 buf = cpu_to_le32(data); |
return pci_write_data(d, &buf, pos, 4); |
} |
int |
pci_write_block(struct pci_dev *d, int pos, byte *buf, int len) |
int pci_write_block(struct pci_dev *d, int pos, byte * buf, int len) |
{ |
if (pos < d->cache_len) |
{ |
int l = (pos + len >= d->cache_len) ? (d->cache_len - pos) : len; |
if (pos < d->cache_len) { |
int l = |
(pos + len >= |
d->cache_len) ? (d->cache_len - pos) : len; |
memcpy(d->cache + pos, buf, l); |
} |
return d->methods->write(d, pos, buf, len); |
} |
int |
pci_fill_info(struct pci_dev *d, int flags) |
int pci_fill_info(struct pci_dev *d, int flags) |
{ |
if (flags & PCI_FILL_RESCAN) |
{ |
if (flags & PCI_FILL_RESCAN) { |
flags &= ~PCI_FILL_RESCAN; |
d->known_fields = 0; |
} |
if (flags & ~d->known_fields) |
d->known_fields |= d->methods->fill_info(d, flags & ~d->known_fields); |
d->known_fields |= |
d->methods->fill_info(d, flags & ~d->known_fields); |
return d->known_fields; |
} |
void |
pci_setup_cache(struct pci_dev *d, byte *cache, int len) |
void pci_setup_cache(struct pci_dev *d, byte * cache, int len) |
{ |
d->cache = cache; |
d->cache_len = len; |
/uspace/trunk/pci/libpci/internal.h |
---|
29,7 → 29,8 |
void pci_generic_scan(struct pci_access *); |
int pci_generic_fill_info(struct pci_dev *, int flags); |
int pci_generic_block_read(struct pci_dev *, int pos, byte *buf, int len); |
int pci_generic_block_write(struct pci_dev *, int pos, byte *buf, int len); |
int pci_generic_block_write(struct pci_dev *, int pos, byte * buf, |
int len); |
void *pci_malloc(struct pci_access *, int); |
void pci_mfree(void *); |
/uspace/trunk/pci/libpci/names.c |
---|
59,8 → 59,7 |
{ |
struct id_bucket *buck = a->current_id_bucket; |
unsigned int pos; |
if (!buck || buck->full + size > BUCKET_SIZE) |
{ |
if (!buck || buck->full + size > BUCKET_SIZE) { |
buck = pci_malloc(a, BUCKET_SIZE); |
buck->next = a->current_id_bucket; |
a->current_id_bucket = buck; |
84,7 → 83,8 |
return h % HASH_SIZE; |
} |
static struct id_entry *id_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4) |
static struct id_entry *id_lookup(struct pci_access *a, int cat, int id1, |
int id2, int id3, int id4) |
{ |
struct id_entry *n; |
u32 id12 = id_pair(id1, id2); |
96,7 → 96,8 |
return n; |
} |
static int id_insert(struct pci_access *a, int cat, int id1, int id2, int id3, int id4, byte *text) |
static int id_insert(struct pci_access *a, int cat, int id1, int id2, |
int id3, int id4, byte * text) |
{ |
u32 id12 = id_pair(id1, id2); |
u32 id34 = id_pair(id3, id4); |
121,8 → 122,7 |
static int id_hex(byte *p, int cnt) |
{ |
int x = 0; |
while (cnt--) |
{ |
while (cnt--) { |
x <<= 4; |
if (*p >= '0' && *p <= '9') |
x += (*p - '0'); |
173,17 → 173,14 |
p++; |
nest = p - line; |
if (!nest) /* Top-level entries */ |
{ |
if (p[0] == 'C' && p[1] == ' ') /* Class block */ |
{ |
if ((id1 = id_hex(p+2, 2)) < 0 || !id_white_p(p[4])) |
if (!nest) { /* Top-level entries */ |
if (p[0] == 'C' && p[1] == ' ') { /* Class block */ |
if ((id1 = id_hex(p + 2, 2)) < 0 |
|| !id_white_p(p[4])) |
return parse_error; |
cat = ID_CLASS; |
p += 5; |
} |
else if (p[0] == 'S' && p[1] == ' ') |
{ /* Generic subsystem block */ |
} else if (p[0] == 'S' && p[1] == ' ') { /* Generic subsystem block */ |
if ((id1 = id_hex(p+2, 4)) < 0 || p[6]) |
return parse_error; |
if (!id_lookup(a, ID_VENDOR, id1, 0, 0, 0)) |
190,30 → 187,27 |
return "Vendor does not exist"; |
cat = ID_GEN_SUBSYSTEM; |
continue; |
} |
else if (p[0] >= 'A' && p[0] <= 'Z' && p[1] == ' ') |
{ /* Unrecognized block (RFU) */ |
} else if (p[0] >= 'A' && p[0] <= 'Z' && p[1] == ' ') { /* Unrecognized block (RFU) */ |
cat = ID_UNKNOWN; |
continue; |
} |
else /* Vendor ID */ |
{ |
if ((id1 = id_hex(p, 4)) < 0 || !id_white_p(p[4])) |
} else { /* Vendor ID */ |
if ((id1 = id_hex(p, 4)) < 0 |
|| !id_white_p(p[4])) |
return parse_error; |
cat = ID_VENDOR; |
p += 5; |
} |
id2 = id3 = id4 = 0; |
} |
else if (cat == ID_UNKNOWN) /* Nested entries in RFU blocks are skipped */ |
} else if (cat == ID_UNKNOWN) /* Nested entries in RFU blocks are skipped */ |
continue; |
else if (nest == 1) /* Nesting level 1 */ |
switch (cat) |
{ |
switch (cat) { |
case ID_VENDOR: |
case ID_DEVICE: |
case ID_SUBSYSTEM: |
if ((id2 = id_hex(p, 4)) < 0 || !id_white_p(p[4])) |
if ((id2 = id_hex(p, 4)) < 0 |
|| !id_white_p(p[4])) |
return parse_error; |
p += 5; |
cat = ID_DEVICE; |
220,7 → 214,8 |
id3 = id4 = 0; |
break; |
case ID_GEN_SUBSYSTEM: |
if ((id2 = id_hex(p, 4)) < 0 || !id_white_p(p[4])) |
if ((id2 = id_hex(p, 4)) < 0 |
|| !id_white_p(p[4])) |
return parse_error; |
p += 5; |
id3 = id4 = 0; |
228,7 → 223,8 |
case ID_CLASS: |
case ID_SUBCLASS: |
case ID_PROGIF: |
if ((id2 = id_hex(p, 2)) < 0 || !id_white_p(p[2])) |
if ((id2 = id_hex(p, 2)) < 0 |
|| !id_white_p(p[2])) |
return parse_error; |
p += 3; |
cat = ID_SUBCLASS; |
236,13 → 232,14 |
break; |
default: |
return parse_error; |
} |
else if (nest == 2) /* Nesting level 2 */ |
switch (cat) |
{ |
} else if (nest == 2) /* Nesting level 2 */ |
switch (cat) { |
case ID_DEVICE: |
case ID_SUBSYSTEM: |
if ((id3 = id_hex(p, 4)) < 0 || !id_white_p(p[4]) || (id4 = id_hex(p+5, 4)) < 0 || !id_white_p(p[9])) |
if ((id3 = id_hex(p, 4)) < 0 |
|| !id_white_p(p[4]) |
|| (id4 = id_hex(p + 5, 4)) < 0 |
|| !id_white_p(p[9])) |
return parse_error; |
p += 10; |
cat = ID_SUBSYSTEM; |
250,7 → 247,8 |
case ID_CLASS: |
case ID_SUBCLASS: |
case ID_PROGIF: |
if ((id3 = id_hex(p, 2)) < 0 || !id_white_p(p[2])) |
if ((id3 = id_hex(p, 2)) < 0 |
|| !id_white_p(p[2])) |
return parse_error; |
p += 3; |
cat = ID_PROGIF; |
258,8 → 256,7 |
break; |
default: |
return parse_error; |
} |
else /* Nesting level 3 or more */ |
} else /* Nesting level 3 or more */ |
return parse_error; |
while (id_white_p(*p)) |
p++; |
271,8 → 268,7 |
return NULL; |
} |
int |
pci_load_name_list(struct pci_access *a) |
int pci_load_name_list(struct pci_access *a) |
{ |
int lino; |
const char *err; |
286,13 → 282,11 |
return 1; |
} |
void |
pci_free_name_list(struct pci_access *a) |
void pci_free_name_list(struct pci_access *a) |
{ |
pci_mfree(a->id_hash); |
a->id_hash = NULL; |
while (a->current_id_bucket) |
{ |
while (a->current_id_bucket) { |
struct id_bucket *buck = a->current_id_bucket; |
a->current_id_bucket = buck->next; |
pci_mfree(buck); |
299,7 → 293,8 |
} |
} |
static struct id_entry *id_lookup_subsys(struct pci_access *a, int iv, int id, int isv, int isd) |
static struct id_entry *id_lookup_subsys(struct pci_access *a, int iv, |
int id, int isv, int isd) |
{ |
struct id_entry *d = NULL; |
if (iv > 0 && id > 0) /* Per-device lookup */ |
311,8 → 306,8 |
return d; |
} |
char * |
pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, ...) |
char *pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, |
...) |
{ |
va_list args; |
int num, res, synth; |
322,29 → 317,23 |
va_start(args, flags); |
num = 0; |
if ((flags & PCI_LOOKUP_NUMERIC) || a->numeric_ids) |
{ |
if ((flags & PCI_LOOKUP_NUMERIC) || a->numeric_ids) { |
flags &= ~PCI_LOOKUP_NUMERIC; |
num = 1; |
} |
else if (!a->id_hash) |
{ |
} else if (!a->id_hash) { |
if (!pci_load_name_list(a)) |
num = a->numeric_ids = 1; |
} |
if (flags & PCI_LOOKUP_NO_NUMBERS) |
{ |
if (flags & PCI_LOOKUP_NO_NUMBERS) { |
flags &= ~PCI_LOOKUP_NO_NUMBERS; |
synth = 0; |
if (num) |
return NULL; |
} |
else |
} else |
synth = 1; |
switch (flags) |
{ |
switch (flags) { |
case PCI_LOOKUP_VENDOR: |
iv = va_arg(args, int); |
if (num) |
352,7 → 341,8 |
else if (v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0)) |
return (char *) v->name; |
else |
res = snprintf(buf, size, "Unknown vendor %04x", iv); |
res = |
snprintf(buf, size, "Unknown vendor %04x", iv); |
break; |
case PCI_LOOKUP_DEVICE: |
iv = va_arg(args, int); |
362,7 → 352,8 |
else if (d = id_lookup(a, ID_DEVICE, iv, id, 0, 0)) |
return (char *) d->name; |
else if (synth) |
res = snprintf(buf, size, "Unknown device %04x", id); |
res = |
snprintf(buf, size, "Unknown device %04x", id); |
else |
return NULL; |
break; |
371,18 → 362,25 |
id = va_arg(args, int); |
if (num) |
res = snprintf(buf, size, "%04x:%04x", iv, id); |
else |
{ |
else { |
v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0); |
d = id_lookup(a, ID_DEVICE, iv, id, 0, 0); |
if (v && d) |
res = snprintf(buf, size, "%s %s", v->name, d->name); |
res = |
snprintf(buf, size, "%s %s", v->name, |
d->name); |
else if (!synth) |
return NULL; |
else if (!v) |
res = snprintf(buf, size, "Unknown device %04x:%04x", iv, id); |
res = |
snprintf(buf, size, |
"Unknown device %04x:%04x", |
iv, id); |
else /* !d */ |
res = snprintf(buf, size, "%s Unknown device %04x", v->name, id); |
res = |
snprintf(buf, size, |
"%s Unknown device %04x", |
v->name, id); |
} |
break; |
case PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR: |
392,7 → 390,9 |
else if (v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0)) |
return (char *) v->name; |
else if (synth) |
res = snprintf(buf, size, "Unknown vendor %04x", isv); |
res = |
snprintf(buf, size, "Unknown vendor %04x", |
isv); |
else |
return NULL; |
break; |
406,7 → 406,9 |
else if (d = id_lookup_subsys(a, iv, id, isv, isd)) |
return (char *) d->name; |
else if (synth) |
res = snprintf(buf, size, "Unknown device %04x", isd); |
res = |
snprintf(buf, size, "Unknown device %04x", |
isd); |
else |
return NULL; |
break; |
417,18 → 419,25 |
isd = va_arg(args, int); |
if (num) |
res = snprintf(buf, size, "%04x:%04x", isv, isd); |
else |
{ |
else { |
v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0); |
d = id_lookup_subsys(a, iv, id, isv, isd); |
if (v && d) |
res = snprintf(buf, size, "%s %s", v->name, d->name); |
res = |
snprintf(buf, size, "%s %s", v->name, |
d->name); |
else if (!synth) |
return NULL; |
else if (!v) |
res = snprintf(buf, size, "Unknown device %04x:%04x", isv, isd); |
res = |
snprintf(buf, size, |
"Unknown device %04x:%04x", |
isv, isd); |
else /* !d */ |
res = snprintf(buf, size, "%s Unknown device %04x", v->name, isd); |
res = |
snprintf(buf, size, |
"%s Unknown device %04x", |
v->name, isd); |
} |
break; |
case PCI_LOOKUP_CLASS: |
435,10 → 444,14 |
icls = va_arg(args, int); |
if (num) |
res = snprintf(buf, size, "%04x", icls); |
else if (cls = id_lookup(a, ID_SUBCLASS, icls >> 8, icls & 0xff, 0, 0)) |
else if (cls = |
id_lookup(a, ID_SUBCLASS, icls >> 8, icls & 0xff, |
0, 0)) |
return (char *) cls->name; |
else if (cls = id_lookup(a, ID_CLASS, icls, 0, 0, 0)) |
res = snprintf(buf, size, "%s [%04x]", cls->name, icls); |
res = |
snprintf(buf, size, "%s [%04x]", cls->name, |
icls); |
else if (synth) |
res = snprintf(buf, size, "Class %04x", icls); |
else |
449,10 → 462,11 |
ipif = va_arg(args, int); |
if (num) |
res = snprintf(buf, size, "%02x", ipif); |
else if (pif = id_lookup(a, ID_PROGIF, icls >> 8, icls & 0xff, ipif, 0)) |
else if (pif = |
id_lookup(a, ID_PROGIF, icls >> 8, icls & 0xff, |
ipif, 0)) |
return (char *) pif->name; |
else if (icls == 0x0101 && !(ipif & 0x70)) |
{ |
else if (icls == 0x0101 && !(ipif & 0x70)) { |
/* IDE controllers have complex prog-if semantics */ |
res = snprintf(buf, size, "%s%s%s%s%s", |
(ipif & 0x80) ? "Master " : "", |
462,8 → 476,7 |
(ipif & 0x01) ? "PriO " : ""); |
if (res > 0 && res < size) |
buf[--res] = 0; |
} |
else if (synth) |
} else if (synth) |
res = snprintf(buf, size, "ProgIf %02x", ipif); |
else |
return NULL; |
/uspace/trunk/pci/libpci/generic.c |
---|
12,27 → 12,25 |
#include "internal.h" |
void |
pci_generic_scan_bus(struct pci_access *a, byte *busmap, int bus) |
void pci_generic_scan_bus(struct pci_access *a, byte * busmap, int bus) |
{ |
int dev, multi, ht; |
struct pci_dev *t; |
a->debug("Scanning bus %02x for devices...\n", bus); |
if (busmap[bus]) |
{ |
a->warning("Bus %02x seen twice (firmware bug). Ignored.", bus); |
if (busmap[bus]) { |
a->warning("Bus %02x seen twice (firmware bug). Ignored.", |
bus); |
return; |
} |
busmap[bus] = 1; |
t = pci_alloc_dev(a); |
t->bus = bus; |
for(dev=0; dev<32; dev++) |
{ |
for (dev = 0; dev < 32; dev++) { |
t->dev = dev; |
multi = 0; |
for(t->func=0; !t->func || multi && t->func<8; t->func++) |
{ |
for (t->func = 0; !t->func || multi && t->func < 8; |
t->func++) { |
u32 vd = pci_read_long(t, PCI_VENDOR_ID); |
struct pci_dev *d; |
51,16 → 49,20 |
d->known_fields = PCI_FILL_IDENT; |
d->hdrtype = ht; |
pci_link_dev(a, d); |
switch (ht) |
{ |
switch (ht) { |
case PCI_HEADER_TYPE_NORMAL: |
break; |
case PCI_HEADER_TYPE_BRIDGE: |
case PCI_HEADER_TYPE_CARDBUS: |
pci_generic_scan_bus(a, busmap, pci_read_byte(t, PCI_SECONDARY_BUS)); |
pci_generic_scan_bus(a, busmap, |
pci_read_byte(t, |
PCI_SECONDARY_BUS)); |
break; |
default: |
a->debug("Device %04x:%02x:%02x.%d has unknown header type %02x.\n", d->domain, d->bus, d->dev, d->func, ht); |
a->debug |
("Device %04x:%02x:%02x.%d has unknown header type %02x.\n", |
d->domain, d->bus, d->dev, d->func, |
ht); |
} |
} |
} |
67,8 → 69,7 |
pci_free_dev(t); |
} |
void |
pci_generic_scan(struct pci_access *a) |
void pci_generic_scan(struct pci_access *a) |
{ |
byte busmap[256]; |
76,26 → 77,23 |
pci_generic_scan_bus(a, busmap, 0); |
} |
int |
pci_generic_fill_info(struct pci_dev *d, int flags) |
int pci_generic_fill_info(struct pci_dev *d, int flags) |
{ |
struct pci_access *a = d->access; |
if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE)) && d->hdrtype < 0) |
if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE)) |
&& d->hdrtype < 0) |
d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f; |
if (flags & PCI_FILL_IDENT) |
{ |
if (flags & PCI_FILL_IDENT) { |
d->vendor_id = pci_read_word(d, PCI_VENDOR_ID); |
d->device_id = pci_read_word(d, PCI_DEVICE_ID); |
} |
if (flags & PCI_FILL_IRQ) |
d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE); |
if (flags & PCI_FILL_BASES) |
{ |
if (flags & PCI_FILL_BASES) { |
int cnt = 0, i; |
bzero(d->base_addr, sizeof(d->base_addr)); |
switch (d->hdrtype) |
{ |
switch (d->hdrtype) { |
case PCI_HEADER_TYPE_NORMAL: |
cnt = 6; |
break; |
106,31 → 104,51 |
cnt = 1; |
break; |
} |
if (cnt) |
{ |
for(i=0; i<cnt; i++) |
{ |
u32 x = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4); |
if (cnt) { |
for (i = 0; i < cnt; i++) { |
u32 x = |
pci_read_long(d, |
PCI_BASE_ADDRESS_0 + |
i * 4); |
if (!x || x == (u32) ~0) |
continue; |
if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) |
if ((x & PCI_BASE_ADDRESS_SPACE) == |
PCI_BASE_ADDRESS_SPACE_IO) |
d->base_addr[i] = x; |
else |
{ |
if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64) |
else { |
if ((x & |
PCI_BASE_ADDRESS_MEM_TYPE_MASK) |
!= |
PCI_BASE_ADDRESS_MEM_TYPE_64) |
d->base_addr[i] = x; |
else if (i >= cnt-1) |
a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i); |
else |
{ |
u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4); |
a->warning |
("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", |
d->domain, d->bus, |
d->dev, d->func, i); |
else { |
u32 y = |
pci_read_long(d, |
PCI_BASE_ADDRESS_0 |
+ |
(++i) * |
4); |
#ifdef PCI_HAVE_64BIT_ADDRESS |
d->base_addr[i-1] = x | (((pciaddr_t) y) << 32); |
d->base_addr[i - 1] = |
x | (((pciaddr_t) y) << |
32); |
#else |
if (y) |
a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func); |
a->warning |
("%04x:%02x:%02x.%d 64-bit device address ignored.", |
d->domain, |
d->bus, |
d->dev, |
d->func); |
else |
d->base_addr[i-1] = x; |
d->base_addr[i - |
1] = |
x; |
#endif |
} |
} |
137,12 → 155,10 |
} |
} |
} |
if (flags & PCI_FILL_ROM_BASE) |
{ |
if (flags & PCI_FILL_ROM_BASE) { |
int reg = 0; |
d->rom_base_addr = 0; |
switch (d->hdrtype) |
{ |
switch (d->hdrtype) { |
case PCI_HEADER_TYPE_NORMAL: |
reg = PCI_ROM_ADDRESS; |
break; |
150,8 → 166,7 |
reg = PCI_ROM_ADDRESS1; |
break; |
} |
if (reg) |
{ |
if (reg) { |
u32 u = pci_read_long(d, reg); |
if (u != 0xffffffff) |
d->rom_base_addr = u; |
162,31 → 177,36 |
static int |
pci_generic_block_op(struct pci_dev *d, int pos, byte *buf, int len, |
int (*r)(struct pci_dev *d, int pos, byte *buf, int len)) |
int (*r) (struct pci_dev * d, int pos, byte * buf, |
int len)) |
{ |
if ((pos & 1) && len >= 1) |
{ |
if ((pos & 1) && len >= 1) { |
if (!r(d, pos, buf, 1)) |
return 0; |
pos++; buf++; len--; |
pos++; |
buf++; |
len--; |
} |
if ((pos & 3) && len >= 2) |
{ |
if ((pos & 3) && len >= 2) { |
if (!r(d, pos, buf, 2)) |
return 0; |
pos += 2; buf += 2; len -= 2; |
pos += 2; |
buf += 2; |
len -= 2; |
} |
while (len >= 4) |
{ |
while (len >= 4) { |
if (!r(d, pos, buf, 4)) |
return 0; |
pos += 4; buf += 4; len -= 4; |
pos += 4; |
buf += 4; |
len -= 4; |
} |
if (len >= 2) |
{ |
if (len >= 2) { |
if (!r(d, pos, buf, 2)) |
return 0; |
pos += 2; buf += 2; len -= 2; |
pos += 2; |
buf += 2; |
len -= 2; |
} |
if (len && !r(d, pos, buf, 1)) |
return 0; |
193,14 → 213,14 |
return 1; |
} |
int |
pci_generic_block_read(struct pci_dev *d, int pos, byte *buf, int len) |
int pci_generic_block_read(struct pci_dev *d, int pos, byte * buf, int len) |
{ |
return pci_generic_block_op(d, pos, buf, len, d->access->methods->read); |
return pci_generic_block_op(d, pos, buf, len, |
d->access->methods->read); |
} |
int |
pci_generic_block_write(struct pci_dev *d, int pos, byte *buf, int len) |
int pci_generic_block_write(struct pci_dev *d, int pos, byte * buf, int len) |
{ |
return pci_generic_block_op(d, pos, buf, len, d->access->methods->write); |
return pci_generic_block_op(d, pos, buf, len, |
d->access->methods->write); |
} |