From 2d3e88cd9e999219b2101e65b3390d628941126e Mon Sep 17 00:00:00 2001 From: imp Date: Thu, 29 Dec 2005 01:43:47 +0000 Subject: Implement /dev/cardbus%d.cis, same thing as /dev/pccard%d.cis. There are some rough edges with this still, but it seems to work well enough to commit. --- sys/dev/cardbus/cardbus_cis.c | 120 +++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 71 deletions(-) (limited to 'sys/dev/cardbus/cardbus_cis.c') diff --git a/sys/dev/cardbus/cardbus_cis.c b/sys/dev/cardbus/cardbus_cis.c index 4d7b973..552d32d 100644 --- a/sys/dev/cardbus/cardbus_cis.c +++ b/sys/dev/cardbus/cardbus_cis.c @@ -58,45 +58,33 @@ extern int cardbus_cis_debug; #define DPRINTF(a) if (cardbus_cis_debug) printf a #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x -struct tuple_callbacks; - -typedef int (tuple_cb) (device_t cbdev, device_t child, int id, int len, - uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info); - -struct tuple_callbacks { - int id; - char *name; - tuple_cb *func; -}; - static int decode_tuple_generic(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info); + struct tuple_callbacks *info, void *); static int decode_tuple_linktarget(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info); + struct tuple_callbacks *info, void *); static int decode_tuple_vers_1(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info); + struct tuple_callbacks *info, void *); static int decode_tuple_funcid(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info); + struct tuple_callbacks *info, void *); static int decode_tuple_manfid(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info); + struct tuple_callbacks *info, void *); static int decode_tuple_funce(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info); + struct tuple_callbacks *info, void *); static int decode_tuple_bar(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info); + struct tuple_callbacks *info, void *); static int decode_tuple_unhandled(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info); + struct tuple_callbacks *info, void *); static int decode_tuple_end(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info); + struct tuple_callbacks *info, void *); static int cardbus_read_tuple_conf(device_t cbdev, device_t child, uint32_t start, uint32_t *off, int *tupleid, int *len, @@ -113,9 +101,8 @@ static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start, int *rid); static int decode_tuple(device_t cbdev, device_t child, int tupleid, int len, uint8_t *tupledata, uint32_t start, - uint32_t *off, struct tuple_callbacks *callbacks); -static int cardbus_parse_cis(device_t cbdev, device_t child, - struct tuple_callbacks *callbacks); + uint32_t *off, struct tuple_callbacks *callbacks, + void *); #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC } @@ -139,7 +126,7 @@ static char *funcnames[] = { static int decode_tuple_generic(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info) + struct tuple_callbacks *info, void *argp) { int i; @@ -162,7 +149,7 @@ decode_tuple_generic(device_t cbdev, device_t child, int id, static int decode_tuple_linktarget(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info) + struct tuple_callbacks *info, void *argp) { int i; @@ -180,7 +167,7 @@ decode_tuple_linktarget(device_t cbdev, device_t child, int id, tupledata[2] != 'S') { printf("Invalid data for CIS Link Target!\n"); decode_tuple_generic(cbdev, child, id, len, tupledata, - start, off, info); + start, off, info, argp); return (EINVAL); } return (0); @@ -189,7 +176,7 @@ decode_tuple_linktarget(device_t cbdev, device_t child, int id, static int decode_tuple_vers_1(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info) + struct tuple_callbacks *info, void *argp) { int i; @@ -212,7 +199,7 @@ decode_tuple_vers_1(device_t cbdev, device_t child, int id, static int decode_tuple_funcid(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info) + struct tuple_callbacks *info, void *argp) { struct cardbus_devinfo *dinfo = device_get_ivars(child); int numnames = sizeof(funcnames) / sizeof(funcnames[0]); @@ -225,7 +212,7 @@ decode_tuple_funcid(device_t cbdev, device_t child, int id, printf("%s", funcnames[tupledata[i]]); else printf("Unknown(%d)", tupledata[i]); - if (i < len-1) + if (i < len - 1) printf(", "); } printf("\n"); @@ -238,7 +225,7 @@ decode_tuple_funcid(device_t cbdev, device_t child, int id, static int decode_tuple_manfid(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info) + struct tuple_callbacks *info, void *argp) { struct cardbus_devinfo *dinfo = device_get_ivars(child); int i; @@ -260,7 +247,7 @@ decode_tuple_manfid(device_t cbdev, device_t child, int id, static int decode_tuple_funce(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info) + struct tuple_callbacks *info, void *argp) { struct cardbus_devinfo *dinfo = device_get_ivars(child); int type, i; @@ -295,7 +282,7 @@ decode_tuple_funce(device_t cbdev, device_t child, int id, static int decode_tuple_bar(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info) + struct tuple_callbacks *info, void *argp) { struct cardbus_devinfo *dinfo = device_get_ivars(child); int type; @@ -390,17 +377,17 @@ decode_tuple_bar(device_t cbdev, device_t child, int id, static int decode_tuple_unhandled(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info) + struct tuple_callbacks *info, void *argp) { /* Make this message suck less XXX */ printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len); - return (-1); + return (EINVAL); } static int decode_tuple_end(device_t cbdev, device_t child, int id, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *info) + struct tuple_callbacks *info, void *argp) { if (cardbus_cis_debug) printf("CIS reading done\n"); @@ -479,8 +466,9 @@ cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid, { if (res != (struct resource*)~0UL) { bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); - pci_write_config(child, rid, 0, 4); - PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY); + if (rid == PCIM_CIS_ASI_ROM) + pci_write_config(child, rid, pci_read_config(child, + rid, 4) & ~PCIR_BIOS, 4); } } @@ -488,14 +476,14 @@ static struct resource * cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start, int *rid) { - uint32_t testval; - uint32_t size; struct resource *res; uint32_t space; space = *start & PCIM_CIS_ASI_MASK; switch (space) { case PCIM_CIS_ASI_TUPLE: + if (cardbus_cis_debug) + device_printf(cbdev, "CIS in PCI config space\n"); /* CIS in PCI config space need no initialization */ return ((struct resource*)~0UL); case PCIM_CIS_ASI_BAR0: @@ -505,9 +493,13 @@ cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start, case PCIM_CIS_ASI_BAR4: case PCIM_CIS_ASI_BAR5: *rid = PCIR_BAR(space - PCIM_CIS_ASI_BAR0); + if (cardbus_cis_debug) + device_printf(cbdev, "CIS in BAR %#x\n", *rid); break; case PCIM_CIS_ASI_ROM: *rid = PCIR_BIOS; + if (cardbus_cis_debug) + device_printf(cbdev, "CIS in option rom\n"); break; default: device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n", @@ -515,35 +507,19 @@ cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start, return (NULL); } - /* figure out how much space we need */ - pci_write_config(child, *rid, 0xffffffff, 4); - testval = pci_read_config(child, *rid, 4); - - /* - * This bit has a different meaning depending if we are dealing - * with a normal BAR or an Option ROM BAR. - */ - if (((testval & 0x1) == 0x1) && (*rid != PCIR_BIOS)) { - device_printf(cbdev, "CIS Space is IO, expecting memory.\n"); - return (NULL); - } - - size = CARDBUS_MAPREG_MEM_SIZE(testval); - /* XXX Is this some kind of hack? */ - if (size < 4096) - size = 4096; /* allocate the memory space to read CIS */ - res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size, - rman_make_alignment_flags(size) | RF_ACTIVE); + res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, 1, + rman_make_alignment_flags(4096) | RF_ACTIVE); if (res == NULL) { device_printf(cbdev, "Unable to allocate resource " "to read CIS.\n"); return (NULL); } - pci_write_config(child, *rid, - rman_get_start(res) | ((*rid == PCIR_BIOS) ? PCIM_BIOS_ENABLE : 0), - 4); PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY); + pci_write_config(child, *rid, rman_get_start(res), 4); + if (*rid == PCIR_BIOS) + pci_write_config(child, *rid, + rman_get_start(res) | PCIM_BIOS_ENABLE, 4); /* Flip to the right ROM image if CIS is in ROM */ if (space == PCIM_CIS_ASI_ROM) { @@ -626,21 +602,21 @@ cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start, static int decode_tuple(device_t cbdev, device_t child, int tupleid, int len, uint8_t *tupledata, uint32_t start, uint32_t *off, - struct tuple_callbacks *callbacks) + struct tuple_callbacks *callbacks, void *argp) { int i; for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) { if (tupleid == callbacks[i].id) return (callbacks[i].func(cbdev, child, tupleid, len, - tupledata, start, off, &callbacks[i])); + tupledata, start, off, &callbacks[i], argp)); } return (callbacks[i].func(cbdev, child, tupleid, len, - tupledata, start, off, NULL)); + tupledata, start, off, NULL, argp)); } -static int +int cardbus_parse_cis(device_t cbdev, device_t child, - struct tuple_callbacks *callbacks) + struct tuple_callbacks *callbacks, void *argp) { uint8_t tupledata[MAXTUPLESIZE]; int tupleid; @@ -656,6 +632,8 @@ cardbus_parse_cis(device_t cbdev, device_t child, device_printf(cbdev, "CIS pointer is 0!\n"); return (ENXIO); } + if (cardbus_cis_debug) + device_printf(cbdev, "CIS pointer is %#x\n", start); off = 0; res = cardbus_read_tuple_init(cbdev, child, &start, &rid); if (res == NULL) { @@ -664,8 +642,8 @@ cardbus_parse_cis(device_t cbdev, device_t child, } do { - if (0 != cardbus_read_tuple(cbdev, child, res, start, &off, - &tupleid, &len, tupledata)) { + if (cardbus_read_tuple(cbdev, child, res, start, &off, + &tupleid, &len, tupledata) != 0) { device_printf(cbdev, "Failed to read CIS.\n"); cardbus_read_tuple_finish(cbdev, child, rid, res); return (ENXIO); @@ -678,7 +656,7 @@ cardbus_parse_cis(device_t cbdev, device_t child, return (EINVAL); } expect_linktarget = decode_tuple(cbdev, child, tupleid, len, - tupledata, start, &off, callbacks); + tupledata, start, &off, callbacks, argp); if (expect_linktarget != 0) { device_printf(cbdev, "Parsing failed with %d\n", expect_linktarget); @@ -710,7 +688,7 @@ cardbus_do_cis(device_t cbdev, device_t child) MAKETUPLE(GENERIC, generic), }; - ret = cardbus_parse_cis(cbdev, child, init_callbacks); + ret = cardbus_parse_cis(cbdev, child, init_callbacks, NULL); if (ret < 0) return (ret); return 0; -- cgit v1.1