diff options
author | jon <jon@FreeBSD.org> | 2001-01-06 18:04:55 +0000 |
---|---|---|
committer | jon <jon@FreeBSD.org> | 2001-01-06 18:04:55 +0000 |
commit | e564c617f8aadbc77f1edc9eddeb5206cc9fb74c (patch) | |
tree | 33661c6ea35ebf2bdf7d737967b65b1ea6e1b1fa /sys/dev/cardbus/cardbus_cis.c | |
parent | 56e99b7d35d909eaef84dafc091867116a08e54f (diff) | |
download | FreeBSD-src-e564c617f8aadbc77f1edc9eddeb5206cc9fb74c.zip FreeBSD-src-e564c617f8aadbc77f1edc9eddeb5206cc9fb74c.tar.gz |
* Better kld support in pccbb/cardbus
- pccbb no longer needs to remember whether a card is inserted.
- pccbb reissues insertion on load of cardbus/pccard modules.
- got rid of unnecessary delays in power functions.
- Cardbus children are no longer deleted if probe/attach fails.
- non-attached child devices are reprobed at driver_added.
* CARD interface to read CIS
- added card_cis_read/card_cis_free interface to read arbitrary CIS
data. This currently is only implemented in cardbus.
* pccard begins to work
- pccard can now use higher memory space (and uses it by default).
- set_memory_offset interface changed.
- fixed ccr access, which was broken at multiple locations.
- implement an interrupt handler - pccard can now share interrupts.
- resource alloc/release/activate/deactivate functions gutted: some
resources are allocated by the bridge before the child device is
probed or attached. Thus the resource "belongs" to the bridge, and
the pccard_*_resource functions need to fudge the owner/rid.
- changed some error conditions to panics to speed debugging.
* Mutex fix - Giant is entered at the beginning of thread
Diffstat (limited to 'sys/dev/cardbus/cardbus_cis.c')
-rw-r--r-- | sys/dev/cardbus/cardbus_cis.c | 241 |
1 files changed, 179 insertions, 62 deletions
diff --git a/sys/dev/cardbus/cardbus_cis.c b/sys/dev/cardbus/cardbus_cis.c index 2845660..8d2059b 100644 --- a/sys/dev/cardbus/cardbus_cis.c +++ b/sys/dev/cardbus/cardbus_cis.c @@ -37,6 +37,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/malloc.h> #include <sys/bus.h> #include <machine/bus.h> @@ -48,6 +49,8 @@ #include <dev/cardbus/cardbusreg.h> #include <dev/cardbus/cardbus_cis.h> +#include "card_if.h" + #if defined CARDBUS_DEBUG #define STATIC #define DPRINTF(a) printf a @@ -63,7 +66,7 @@ static const char rcsid[] = "$FreeBSD$"; #endif -struct tupleinfo; +struct tuple_callbacks; static int cardbus_read_tuple_conf(device_t dev, device_t child, u_int32_t *start, u_int32_t *off, @@ -78,13 +81,19 @@ static int cardbus_read_tuple(device_t dev, device_t child, u_int32_t *start, u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata); static int decode_tuple(device_t dev, device_t child, int tupleid, int len, - u_int8_t *tupledata, u_int32_t *start, u_int32_t *off); + u_int8_t *tupledata, u_int32_t *start, u_int32_t *off, + struct tuple_callbacks *callbacks); +static int cardbus_parse_cis(device_t dev, device_t child, + struct tuple_callbacks *callbacks); -#define DECODE_PROTOTYPE(NAME) static int decode_tuple_ ## NAME \ +#define DECODE_PARAMS \ (device_t dev, device_t child, int id, int len, \ u_int8_t *tupledata, u_int32_t *start, u_int32_t *off, \ - struct tupleinfo *info) + struct tuple_callbacks *info) +#define DECODE_PROTOTYPE(NAME) static int decode_tuple_ ## NAME DECODE_PARAMS DECODE_PROTOTYPE(generic); +DECODE_PROTOTYPE(nothing); +DECODE_PROTOTYPE(copy); DECODE_PROTOTYPE(bar); DECODE_PROTOTYPE(linktarget); DECODE_PROTOTYPE(vers_1); @@ -94,54 +103,12 @@ DECODE_PROTOTYPE(funce); DECODE_PROTOTYPE(end); DECODE_PROTOTYPE(unhandled); -static struct tupleinfo { - u_int8_t id; +struct tuple_callbacks { + int id; char* name; - int (*func)(device_t dev, device_t child, int id, int len, - u_int8_t *tupledata, u_int32_t *start, u_int32_t *off, - struct tupleinfo *info); -} tupleinfo[] = { -#define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC } - MAKETUPLE(NULL, generic), - MAKETUPLE(DEVICE, generic), - MAKETUPLE(LONG_LINK_CB, unhandled), - MAKETUPLE(INDIRECT, unhandled), - MAKETUPLE(CONFIG_CB, generic), - MAKETUPLE(CFTABLE_ENTRY_CB, generic), - MAKETUPLE(LONGLINK_MFC, unhandled), - MAKETUPLE(BAR, bar), - MAKETUPLE(PWR_MGMNT, generic), - MAKETUPLE(EXTDEVICE, generic), - MAKETUPLE(CHECKSUM, generic), - MAKETUPLE(LONGLINK_A, unhandled), - MAKETUPLE(LONGLINK_C, unhandled), - MAKETUPLE(LINKTARGET, linktarget), - MAKETUPLE(NO_LINK, generic), - MAKETUPLE(VERS_1, vers_1), - MAKETUPLE(ALTSTR, generic), - MAKETUPLE(DEVICE_A, generic), - MAKETUPLE(JEDEC_C, generic), - MAKETUPLE(JEDEC_A, generic), - MAKETUPLE(CONFIG, generic), - MAKETUPLE(CFTABLE_ENTRY, generic), - MAKETUPLE(DEVICE_OC, generic), - MAKETUPLE(DEVICE_OA, generic), - MAKETUPLE(DEVICE_GEO, generic), - MAKETUPLE(DEVICE_GEO_A, generic), - MAKETUPLE(MANFID, manfid), - MAKETUPLE(FUNCID, funcid), - MAKETUPLE(FUNCE, funce), - MAKETUPLE(SWIL, generic), - MAKETUPLE(VERS_2, generic), - MAKETUPLE(FORMAT, generic), - MAKETUPLE(GEOMETRY, generic), - MAKETUPLE(BYTEORDER, generic), - MAKETUPLE(DATE, generic), - MAKETUPLE(BATTERY, generic), - MAKETUPLE(ORG, generic), - MAKETUPLE(END, end), -#undef MAKETUPLE + int (*func) DECODE_PARAMS; }; +#define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC } static char* funcnames[] = { "Multi-Functioned", @@ -156,6 +123,9 @@ static char* funcnames[] = { "Security" }; +static struct cis_tupleinfo* cisread_buf; +static int ncisread_buf; + DECODE_PROTOTYPE(generic) { #ifdef CARDBUS_DEBUG @@ -176,6 +146,32 @@ DECODE_PROTOTYPE(generic) return 0; } +DECODE_PROTOTYPE(nothing) +{ + return 0; +} + +DECODE_PROTOTYPE(copy) +{ + struct cis_tupleinfo* tmpbuf; + + tmpbuf = malloc(sizeof(struct cis_tupleinfo)*(ncisread_buf+1), + M_DEVBUF, M_WAITOK); + if (ncisread_buf > 0) { + memcpy(tmpbuf, cisread_buf, + sizeof(struct cis_tupleinfo)*ncisread_buf); + free(cisread_buf, M_DEVBUF); + } + cisread_buf = tmpbuf; + + cisread_buf[ncisread_buf].id = id; + cisread_buf[ncisread_buf].len = len; + cisread_buf[ncisread_buf].data = malloc(len, M_DEVBUF, M_WAITOK); + memcpy (cisread_buf[ncisread_buf].data, tupledata, len); + ncisread_buf++; + return 0; +} + DECODE_PROTOTYPE(linktarget) { #ifdef CARDBUS_DEBUG @@ -277,7 +273,7 @@ DECODE_PROTOTYPE(bar) if (bar < 0 || bar > 5 || (type == SYS_RES_IOPORT && bar == 5)) { device_printf(dev, "Invalid BAR number: %02x(%02x)\n", reg, bar); - return EINVAL; + return 0; } bar = CARDBUS_BASE0_REG + bar * 4; DEVPRINTF((dev, "Opening BAR: type=%s, bar=%02x, len=%04x\n", @@ -299,6 +295,7 @@ DECODE_PROTOTYPE(unhandled) DECODE_PROTOTYPE(end) { + printf("CIS reading done\n"); return 0; } @@ -451,27 +448,29 @@ cardbus_read_tuple(device_t dev, device_t child, u_int32_t *start, static int decode_tuple(device_t dev, device_t child, int tupleid, int len, - u_int8_t *tupledata, u_int32_t *start, u_int32_t *off) + u_int8_t *tupledata, u_int32_t *start, u_int32_t *off, + struct tuple_callbacks *callbacks) { int i; - int numtupleids = sizeof(tupleinfo)/sizeof(tupleinfo[0]); - for (i = 0; i < numtupleids; i++) { - if (tupleid == tupleinfo[i].id) - return tupleinfo[i].func(dev, child, tupleid, len, + for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) { + if (tupleid == callbacks[i].id) + return callbacks[i].func(dev, child, tupleid, len, tupledata, start, off, - &tupleinfo[i]); + &callbacks[i]); } if (tupleid < CISTPL_CUSTOMSTART) { device_printf(dev, "Undefined tuple encountered, CIS parsing terminated\n"); return EINVAL; } - return decode_tuple_generic(dev, child, tupleid, len, tupledata, - start, off, NULL); + return callbacks[i].func(dev, child, tupleid, len, + tupledata, start, off, + NULL); } -int -cardbus_do_cis(device_t dev, device_t child) +static int +cardbus_parse_cis(device_t dev, device_t child, + struct tuple_callbacks *callbacks) { u_int8_t tupledata[MAXTUPLESIZE]; int tupleid; @@ -493,10 +492,128 @@ cardbus_do_cis(device_t dev, device_t child) return EINVAL; } expect_linktarget = decode_tuple(dev, child, tupleid, len, - tupledata, &start, &off); + tupledata, &start, &off, + callbacks); if (expect_linktarget != 0) return expect_linktarget; } while (tupleid != CISTPL_END); return 0; } +int +cardbus_cis_read(device_t dev, device_t child, u_int8_t id, + struct cis_tupleinfo** buff, int* nret) +{ + struct tuple_callbacks cisread_callbacks[] = { + MAKETUPLE(NULL, nothing), + /* first entry will be overwritten */ + MAKETUPLE(NULL, nothing), + MAKETUPLE(DEVICE, nothing), + MAKETUPLE(LONG_LINK_CB, unhandled), + MAKETUPLE(INDIRECT, unhandled), + MAKETUPLE(CONFIG_CB, nothing), + MAKETUPLE(CFTABLE_ENTRY_CB, nothing), + MAKETUPLE(LONGLINK_MFC, unhandled), + MAKETUPLE(BAR, nothing), + MAKETUPLE(PWR_MGMNT, nothing), + MAKETUPLE(EXTDEVICE, nothing), + MAKETUPLE(CHECKSUM, nothing), + MAKETUPLE(LONGLINK_A, unhandled), + MAKETUPLE(LONGLINK_C, unhandled), + MAKETUPLE(LINKTARGET, nothing), + MAKETUPLE(NO_LINK, nothing), + MAKETUPLE(VERS_1, nothing), + MAKETUPLE(ALTSTR, nothing), + MAKETUPLE(DEVICE_A, nothing), + MAKETUPLE(JEDEC_C, nothing), + MAKETUPLE(JEDEC_A, nothing), + MAKETUPLE(CONFIG, nothing), + MAKETUPLE(CFTABLE_ENTRY, nothing), + MAKETUPLE(DEVICE_OC, nothing), + MAKETUPLE(DEVICE_OA, nothing), + MAKETUPLE(DEVICE_GEO, nothing), + MAKETUPLE(DEVICE_GEO_A, nothing), + MAKETUPLE(MANFID, nothing), + MAKETUPLE(FUNCID, nothing), + MAKETUPLE(FUNCE, nothing), + MAKETUPLE(SWIL, nothing), + MAKETUPLE(VERS_2, nothing), + MAKETUPLE(FORMAT, nothing), + MAKETUPLE(GEOMETRY, nothing), + MAKETUPLE(BYTEORDER, nothing), + MAKETUPLE(DATE, nothing), + MAKETUPLE(BATTERY, nothing), + MAKETUPLE(ORG, nothing), + MAKETUPLE(END, end), + MAKETUPLE(GENERIC, nothing), + }; + int ret; + + cisread_callbacks[0].id = id; + cisread_callbacks[0].name = "COPY"; + cisread_callbacks[0].func = decode_tuple_copy; + ncisread_buf = 0; + cisread_buf = NULL; + ret = cardbus_parse_cis(dev, child, cisread_callbacks); + + *buff = cisread_buf; + *nret = ncisread_buf; + return ret; +} + +void +cardbus_cis_free(device_t dev, struct cis_tupleinfo *buff, int* nret) +{ + int i; + for (i = 0; i < nret; i++) + free(buff[i].data, M_DEVBUF); + if (nret > 0) + free(buff, M_DEVBUF); +} + +int +cardbus_do_cis(device_t dev, device_t child) +{ + struct tuple_callbacks init_callbacks[] = { + MAKETUPLE(NULL, generic), + MAKETUPLE(DEVICE, generic), + MAKETUPLE(LONG_LINK_CB, unhandled), + MAKETUPLE(INDIRECT, unhandled), + MAKETUPLE(CONFIG_CB, generic), + MAKETUPLE(CFTABLE_ENTRY_CB, generic), + MAKETUPLE(LONGLINK_MFC, unhandled), + MAKETUPLE(BAR, bar), + MAKETUPLE(PWR_MGMNT, generic), + MAKETUPLE(EXTDEVICE, generic), + MAKETUPLE(CHECKSUM, generic), + MAKETUPLE(LONGLINK_A, unhandled), + MAKETUPLE(LONGLINK_C, unhandled), + MAKETUPLE(LINKTARGET, linktarget), + MAKETUPLE(NO_LINK, generic), + MAKETUPLE(VERS_1, vers_1), + MAKETUPLE(ALTSTR, generic), + MAKETUPLE(DEVICE_A, generic), + MAKETUPLE(JEDEC_C, generic), + MAKETUPLE(JEDEC_A, generic), + MAKETUPLE(CONFIG, generic), + MAKETUPLE(CFTABLE_ENTRY, generic), + MAKETUPLE(DEVICE_OC, generic), + MAKETUPLE(DEVICE_OA, generic), + MAKETUPLE(DEVICE_GEO, generic), + MAKETUPLE(DEVICE_GEO_A, generic), + MAKETUPLE(MANFID, manfid), + MAKETUPLE(FUNCID, funcid), + MAKETUPLE(FUNCE, funce), + MAKETUPLE(SWIL, generic), + MAKETUPLE(VERS_2, generic), + MAKETUPLE(FORMAT, generic), + MAKETUPLE(GEOMETRY, generic), + MAKETUPLE(BYTEORDER, generic), + MAKETUPLE(DATE, generic), + MAKETUPLE(BATTERY, generic), + MAKETUPLE(ORG, generic), + MAKETUPLE(END, end), + MAKETUPLE(GENERIC, generic), + }; + return cardbus_parse_cis(dev, child, init_callbacks); +} |