/* $NetBSD: firmware.h,v 1.2 2021/12/18 23:45:33 riastradh Exp $ */ /* SPDX-License-Identifier: MIT */ #ifndef __NVKM_FIRMWARE_H__ #define __NVKM_FIRMWARE_H__ #include #include int nvkm_firmware_get(const struct nvkm_subdev *, const char *fwname, int ver, const struct firmware **); void nvkm_firmware_put(const struct firmware *); int nvkm_firmware_load_blob(const struct nvkm_subdev *subdev, const char *path, const char *name, int ver, struct nvkm_blob *); int nvkm_firmware_load_name(const struct nvkm_subdev *subdev, const char *path, const char *name, int ver, const struct firmware **); #define nvkm_firmware_load(s,l,o,p...) ({ \ struct nvkm_subdev *_s = (s); \ const char *_opts = (o); \ char _option[32]; \ typeof(l[0]) *_list = (l), *_next, *_fwif = NULL; \ int _ver, _fwv, _ret = 0; \ \ snprintf(_option, sizeof(_option), "Nv%sFw", _opts); \ _ver = nvkm_longopt(_s->device->cfgopt, _option, -2); \ if (_ver >= -1) { \ for (_next = _list; !_fwif && _next->load; _next++) { \ if (_next->version == _ver) \ _fwif = _next; \ } \ _ret = _fwif ? 0 : -EINVAL; \ } \ \ if (_ret == 0) { \ snprintf(_option, sizeof(_option), "Nv%sFwVer", _opts); \ _fwv = _fwif ? _fwif->version : -1; \ _ver = nvkm_longopt(_s->device->cfgopt, _option, _fwv); \ for (_next = _fwif ? _fwif : _list; _next->load; _next++) { \ _fwv = (_ver >= 0) ? _ver : _next->version; \ _ret = _next->load(p, _fwv, _next); \ if (_ret == 0 || _ver >= 0) { \ _fwif = _next; \ break; \ } \ } \ } \ \ if (_ret) { \ nvkm_error(_s, "failed to load firmware\n"); \ _fwif = ERR_PTR(_ret); \ } \ \ _fwif; \ }) #endif