Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/bhnd/nvram/bhnd_sprom.c
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <sys/rman.h> | #include <sys/rman.h> | ||||
#include <machine/resource.h> | #include <machine/resource.h> | ||||
#include <dev/bhnd/bhnd.h> | #include <dev/bhnd/bhnd.h> | ||||
#include "bhnd_nvram_if.h" | #include "bhnd_nvram_if.h" | ||||
#include "bhnd_nvram_io.h" | |||||
#include "bhnd_spromvar.h" | #include "bhnd_spromvar.h" | ||||
#define SPROM_LOCK_INIT(sc) \ | |||||
mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \ | |||||
"BHND SPROM lock", MTX_DEF) | |||||
#define SPROM_LOCK(sc) mtx_lock(&(sc)->mtx) | |||||
#define SPROM_UNLOCK(sc) mtx_unlock(&(sc)->mtx) | |||||
#define SPROM_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->mtx, what) | |||||
#define SPROM_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx) | |||||
/** | /** | ||||
* Default bhnd sprom driver implementation of DEVICE_PROBE(). | * Default bhnd sprom driver implementation of DEVICE_PROBE(). | ||||
*/ | */ | ||||
int | int | ||||
bhnd_sprom_probe(device_t dev) | bhnd_sprom_probe(device_t dev) | ||||
{ | { | ||||
/* Quiet by default */ | |||||
if (!bootverbose) | |||||
device_quiet(dev); | |||||
device_set_desc(dev, "SPROM/OTP"); | device_set_desc(dev, "SPROM/OTP"); | ||||
/* Refuse wildcard attachments */ | /* Refuse wildcard attachments */ | ||||
return (BUS_PROBE_NOWILDCARD); | return (BUS_PROBE_NOWILDCARD); | ||||
} | } | ||||
/* Default DEVICE_ATTACH() implementation; assumes a zero offset to the | /* Default DEVICE_ATTACH() implementation; assumes a zero offset to the | ||||
* SPROM data */ | * SPROM data */ | ||||
Show All 13 Lines | |||||
* | * | ||||
* @param dev BHND SPROM device. | * @param dev BHND SPROM device. | ||||
* @param offset Offset to the SPROM data. | * @param offset Offset to the SPROM data. | ||||
*/ | */ | ||||
int | int | ||||
bhnd_sprom_attach(device_t dev, bus_size_t offset) | bhnd_sprom_attach(device_t dev, bus_size_t offset) | ||||
{ | { | ||||
struct bhnd_sprom_softc *sc; | struct bhnd_sprom_softc *sc; | ||||
struct bhnd_nvram_io *io; | |||||
struct bhnd_resource *r; | |||||
bus_size_t r_size, sprom_size; | |||||
int rid; | |||||
int error; | int error; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
sc->dev = dev; | sc->dev = dev; | ||||
io = NULL; | |||||
/* Allocate SPROM resource */ | /* Allocate SPROM resource */ | ||||
sc->sprom_rid = 0; | rid = 0; | ||||
sc->sprom_res = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY, | r = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); | ||||
&sc->sprom_rid, RF_ACTIVE); | if (r == NULL) { | ||||
if (sc->sprom_res == NULL) { | |||||
device_printf(dev, "failed to allocate resources\n"); | device_printf(dev, "failed to allocate resources\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
/* Initialize SPROM shadow */ | /* Determine SPROM size */ | ||||
if ((error = bhnd_sprom_init(&sc->shadow, sc->sprom_res, offset))) | r_size = rman_get_size(r->res); | ||||
if (r_size <= offset || (r_size - offset) > BUS_SPACE_MAXSIZE) { | |||||
device_printf(dev, "invalid sprom offset\n"); | |||||
error = ENXIO; | |||||
goto failed; | goto failed; | ||||
} | |||||
/* Initialize mutex */ | sprom_size = r_size - offset; | ||||
SPROM_LOCK_INIT(sc); | |||||
/* Allocate an I/O context for the SPROM parser. All SPROM reads | |||||
* must be 16-bit aligned */ | |||||
io = bhnd_nvram_iores_new(r, offset, sprom_size, sizeof(uint16_t)); | |||||
if (io == NULL) { | |||||
error = ENXIO; | |||||
goto failed; | |||||
} | |||||
/* Initialize NVRAM data store */ | |||||
error = bhnd_nvram_store_parse_new(&sc->store, io, | |||||
&bhnd_nvram_sprom_class); | |||||
if (error) | |||||
goto failed; | |||||
/* Clean up our temporary I/O context and its backing resource */ | |||||
bhnd_nvram_io_free(io); | |||||
bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r); | |||||
return (0); | return (0); | ||||
failed: | failed: | ||||
bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sprom_rid, | /* Clean up I/O context before releasing its backing resource */ | ||||
sc->sprom_res); | if (io != NULL) | ||||
bhnd_nvram_io_free(io); | |||||
bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r); | |||||
return (error); | return (error); | ||||
} | } | ||||
/** | /** | ||||
* Default bhnd_sprom implementation of DEVICE_RESUME(). | * Default bhnd_sprom implementation of DEVICE_RESUME(). | ||||
*/ | */ | ||||
int | int | ||||
bhnd_sprom_resume(device_t dev) | bhnd_sprom_resume(device_t dev) | ||||
Show All 15 Lines | |||||
*/ | */ | ||||
int | int | ||||
bhnd_sprom_detach(device_t dev) | bhnd_sprom_detach(device_t dev) | ||||
{ | { | ||||
struct bhnd_sprom_softc *sc; | struct bhnd_sprom_softc *sc; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sprom_rid, | bhnd_nvram_store_free(sc->store); | ||||
sc->sprom_res); | |||||
bhnd_sprom_fini(&sc->shadow); | |||||
SPROM_LOCK_DESTROY(sc); | |||||
return (0); | return (0); | ||||
} | } | ||||
/** | /** | ||||
* Default bhnd sprom driver implementation of BHND_NVRAM_GETVAR(). | * Default bhnd sprom driver implementation of BHND_NVRAM_GETVAR(). | ||||
*/ | */ | ||||
static int | static int | ||||
bhnd_sprom_getvar_method(device_t dev, const char *name, void *buf, size_t *len, | bhnd_sprom_getvar_method(device_t dev, const char *name, void *buf, size_t *len, | ||||
bhnd_nvram_type type) | bhnd_nvram_type type) | ||||
{ | { | ||||
struct bhnd_sprom_softc *sc; | struct bhnd_sprom_softc *sc = device_get_softc(dev); | ||||
int error; | |||||
sc = device_get_softc(dev); | return (bhnd_nvram_store_getvar(sc->store, name, buf, len, type)); | ||||
SPROM_LOCK(sc); | |||||
error = bhnd_sprom_getvar(&sc->shadow, name, buf, len, type); | |||||
SPROM_UNLOCK(sc); | |||||
return (error); | |||||
} | } | ||||
/** | /** | ||||
* Default bhnd sprom driver implementation of BHND_NVRAM_SETVAR(). | * Default bhnd sprom driver implementation of BHND_NVRAM_SETVAR(). | ||||
*/ | */ | ||||
static int | static int | ||||
bhnd_sprom_setvar_method(device_t dev, const char *name, const void *buf, | bhnd_sprom_setvar_method(device_t dev, const char *name, const void *buf, | ||||
size_t len, bhnd_nvram_type type) | size_t len, bhnd_nvram_type type) | ||||
{ | { | ||||
struct bhnd_sprom_softc *sc; | struct bhnd_sprom_softc *sc = device_get_softc(dev); | ||||
int error; | |||||
sc = device_get_softc(dev); | return (bhnd_nvram_store_setvar(sc->store, name, buf, len, type)); | ||||
SPROM_LOCK(sc); | |||||
error = bhnd_sprom_setvar(&sc->shadow, name, buf, len, type); | |||||
SPROM_UNLOCK(sc); | |||||
return (error); | |||||
} | } | ||||
static device_method_t bhnd_sprom_methods[] = { | static device_method_t bhnd_sprom_methods[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
DEVMETHOD(device_probe, bhnd_sprom_probe), | DEVMETHOD(device_probe, bhnd_sprom_probe), | ||||
DEVMETHOD(device_attach, bhnd_sprom_attach_meth), | DEVMETHOD(device_attach, bhnd_sprom_attach_meth), | ||||
DEVMETHOD(device_resume, bhnd_sprom_resume), | DEVMETHOD(device_resume, bhnd_sprom_resume), | ||||
DEVMETHOD(device_suspend, bhnd_sprom_suspend), | DEVMETHOD(device_suspend, bhnd_sprom_suspend), | ||||
DEVMETHOD(device_detach, bhnd_sprom_detach), | DEVMETHOD(device_detach, bhnd_sprom_detach), | ||||
/* NVRAM interface */ | /* NVRAM interface */ | ||||
DEVMETHOD(bhnd_nvram_getvar, bhnd_sprom_getvar_method), | DEVMETHOD(bhnd_nvram_getvar, bhnd_sprom_getvar_method), | ||||
DEVMETHOD(bhnd_nvram_setvar, bhnd_sprom_setvar_method), | DEVMETHOD(bhnd_nvram_setvar, bhnd_sprom_setvar_method), | ||||
DEVMETHOD_END | DEVMETHOD_END | ||||
}; | }; | ||||
DEFINE_CLASS_0(bhnd_nvram, bhnd_sprom_driver, bhnd_sprom_methods, sizeof(struct bhnd_sprom_softc)); | DEFINE_CLASS_0(bhnd_nvram_store, bhnd_sprom_driver, bhnd_sprom_methods, sizeof(struct bhnd_sprom_softc)); | ||||
MODULE_VERSION(bhnd_sprom, 1); | MODULE_VERSION(bhnd_sprom, 1); |