# HG changeset patch # Parent 31a84d08ebef96662520d1f25513fdf69525addd Use a lock to protect loading the CIS so there can be only one. This is good from a resource management perspective, but also because the CIS can go off into cloud-coocoo land at times. While the code knows how to deal with that normally, it would deal with that poorly if another thread did it to it behind the scenes. diff -r 31a84d08ebef sys/dev/pccard/pccard.c --- a/sys/dev/pccard/pccard.c +++ b/sys/dev/pccard/pccard.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include #include diff -r 31a84d08ebef sys/dev/pccard/pccard_cis.c --- a/sys/dev/pccard/pccard_cis.c +++ b/sys/dev/pccard/pccard_cis.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include #include @@ -112,6 +114,7 @@ pccard_read_cis(struct pccard_softc *sc) int pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg) { + struct pccard_softc *sc = PCCARD_SOFTC(dev); struct resource *res; int rid; struct pccard_tuple tuple; @@ -133,6 +136,8 @@ pccard_scan_cis(device_t bus, device_t d /* allocate some memory */ + mtx_lock(&sc->sc_cis_mtx); + /* * Some reports from the field suggest that a 64k memory boundary * helps card CIS being able to be read. Try it here and see what @@ -144,6 +149,7 @@ pccard_scan_cis(device_t bus, device_t d PCCARD_CIS_SIZE, RF_ACTIVE | rman_make_alignment_flags(64*1024)); if (res == NULL) { device_printf(dev, "can't alloc memory to read attributes\n"); + mtx_unlock(&sc->sc_cis_mtx); return -1; } CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY, rid, PCCARD_A_MEM_ATTR); @@ -468,6 +474,8 @@ pccard_scan_cis(device_t bus, device_t d done: bus_release_resource(dev, SYS_RES_MEMORY, rid, res); + mtx_unlock(&sc->sc_cis_mtx); + return (ret); } diff -r 31a84d08ebef sys/dev/pccard/pccard_cis_quirks.c --- a/sys/dev/pccard/pccard_cis_quirks.c +++ b/sys/dev/pccard/pccard_cis_quirks.c @@ -35,9 +35,11 @@ */ #include +#include #include #include -#include +#include +#include #include diff -r 31a84d08ebef sys/dev/pccard/pccard_device.c --- a/sys/dev/pccard/pccard_device.c +++ b/sys/dev/pccard/pccard_device.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include @@ -67,14 +69,17 @@ pccard_device_create(struct pccard_softc sc->cisdev = make_dev(&pccard_cdevsw, minor, 0, 0, 0666, "pccard%u.cis", device_get_unit(sc->dev)); sc->cisdev->si_drv1 = sc; + mtx_init(&sc->sc_cis_mtx, device_get_nameunit(sc->dev), "pccard cis", MTX_DEF); return (0); } int pccard_device_destroy(struct pccard_softc *sc) { - if (sc->cisdev) + if (sc->cisdev) { destroy_dev(sc->cisdev); + mtx_destroy(&sc->sc_cis_mtx); + } return (0); } diff -r 31a84d08ebef sys/dev/pccard/pccardvarp.h --- a/sys/dev/pccard/pccardvarp.h +++ b/sys/dev/pccard/pccardvarp.h @@ -169,6 +169,7 @@ struct pccard_softc { /* this stuff is for the socket */ /* this stuff is for the card */ + struct mtx sc_cis_mtx; /* Exclusive mutex for CIS */ struct pccard_card card; int sc_enabled_count; /* num functions enabled */ struct cdev *cisdev;