gr: fallback to legacy paths during firmware lookup
PATCH 1/1 gr: fallback to legacy paths during firmware lookup
Look for firmware files using the legacy ("nouveau/nvxx_fucxxxx") path if they cannot be found in the new, "official" path. User setups were broken by the switch, which is bad.
There are only 4 firmware files we may want to look up that way, so hardcode them into the lookup function. All new firmware files should use the standard "nvidia/<chip>/gr/" path.
--- drm/nouveau/nvkm/engine/gr/gf100.c | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-)
drm/nouveau/nvkm/engine/gr/gf100.c +51 -5
@@ -1756,24 +1756,70 @@ gf100_gr_ = { };int +gf100_gr_ctor_fw_legacy (struct gf100_gr *gr,const char *fwname, +struct gf100_gr_fuc *fuc) +{ +struct nvkm_subdev *subdev = &gr->base.engine.subdev; +struct nvkm_device *device = subdev->device; +const struct firmware *fw; +char f[32 ]; +int ret; + +snprintf (f,sizeof (f),"nouveau/nv%02x_%s" , device->chipset, fwname); + ret =request_firmware (&fw, f, device->dev); +if (ret) { +snprintf (f,sizeof (f),"nouveau/%s" , fwname); + ret =request_firmware (&fw, f, device->dev); +if (ret) { +nvkm_error (subdev,"failed to load %s\n" , fwname); +return ret; + } + } + + fuc->size = fw->size; + fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); +release_firmware (fw); +return (fuc->data !=NULL ) ?0 : -ENOMEM ; +} + +int gf100_gr_ctor_fw (struct gf100_gr *gr,const char *fwname,struct gf100_gr_fuc *fuc) {struct nvkm_subdev *subdev = &gr->base.engine.subdev;struct nvkm_device *device = subdev->device; +const char *legacy_fwname =NULL ;const struct firmware *fw;int ret; ret =nvkm_firmware_get (device, fwname, &fw); -if (ret) { +/* firmware found, success! */ +if (!ret) { + fuc->size = fw->size; + fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); +nvkm_firmware_put (fw); +return (fuc->data !=NULL ) ?0 : -ENOMEM ; + } + +/* see if this firmware has a legacy path */ +if (!strcmp (fwname,"fecs_inst" )) + legacy_fwname ="fuc409c" ; +else if (!strcmp (fwname,"fecs_data" )) + legacy_fwname ="fuc409d" ; +else if (!strcmp (fwname,"gpccs_inst" )) + legacy_fwname ="fuc41ac" ; +else if (!strcmp (fwname,"gpccs_data" )) + legacy_fwname ="fuc41ad" ; + +/* nope, let's just return the error we got */ +if (!legacy_fwname) {nvkm_error (subdev,"failed to load %s\n" , fwname);return ret; } - fuc->size = fw->size; - fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); -nvkm_firmware_put (fw); -return (fuc->data !=NULL ) ?0 : -ENOMEM ; +/* yes, try to load from the legacy path */ +nvkm_debug (subdev,"%s: falling back to legacy path\n" , fwname); +return gf100_gr_ctor_fw_legacy (gr, legacy_fwname, fuc); }int
Signature · 6 lines
2.10.0 _______________________________________________ Nouveau mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/nouveau
A message that is not in the archive (sent off-list or not yet received): 20161102045417.5886-1-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org
Quoted 67 lines · Alexandre Courbot
Look for firmware files using the legacy ("nouveau/nvxx_fucxxxx") path if they cannot be found in the new, "official" path. User setups were broken by the switch, which is bad.
There are only 4 firmware files we may want to look up that way, so hardcode them into the lookup function. All new firmware files should use the standard "nvidia/<chip>/gr/" path.
Fixes 8539b37acef7 ("drm/nouveau/gr: use NVIDIA-provided external firmwares")Signed-off-by Alexandre Courbot <[email protected]>--- drm/nouveau/nvkm/engine/gr/gf100.c | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-)drm/nouveau/nvkm/engine/gr/gf100.c +35
-1@@ -1756,24 +1756,70 @@ gf100_gr_ = { };int +gf100_gr_ctor_fw_legacy (struct gf100_gr *gr,const char *fwname, +struct gf100_gr_fuc *fuc) +{ +struct nvkm_subdev *subdev = &gr->base.engine.subdev; +struct nvkm_device *device = subdev->device; +const struct firmware *fw; +char f[32 ]; +int ret; + +snprintf (f,sizeof (f),"nouveau/nv%02x_%s" , device->chipset, fwname); + ret =request_firmware (&fw, f, device->dev); +if (ret) { +snprintf (f,sizeof (f),"nouveau/%s" , fwname); + ret =request_firmware (&fw, f, device->dev); +if (ret) { +nvkm_error (subdev,"failed to load %s\n" , fwname); +return ret; + } + } + + fuc->size = fw->size; + fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); +release_firmware (fw); +return (fuc->data !=NULL ) ?0 : -ENOMEM ; +} + +int gf100_gr_ctor_fw (struct gf100_gr *gr,const char *fwname,struct gf100_gr_fuc *fuc) {struct nvkm_subdev *subdev = &gr->base.engine.subdev;struct nvkm_device *device = subdev->device; +const char *legacy_fwname =NULL ;const struct firmware *fw;int ret; ret =nvkm_firmware_get (device, fwname, &fw); -if (ret) { +/* firmware found, success! */ +if (!ret) { + fuc->size = fw->size; + fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); +nvkm_firmware_put (fw); +return (fuc->data !=NULL ) ?0 : -ENOMEM ; + }
drm/nouveau/nvkm/engine/gr/gf100.c gf100_gr_ = { · line 1812
Quoted 10 lines
drm/nouveau/nvkm/engine/gr/gf100.c +10
-0+ +/* see if this firmware has a legacy path */ +if (!strcmp (fwname,"fecs_inst" )) + legacy_fwname ="fuc409c" ; +else if (!strcmp (fwname,"fecs_data" )) + legacy_fwname ="fuc409d" ; +else if (!strcmp (fwname,"gpccs_inst" )) + legacy_fwname ="fuc41ac" ; +else if (!strcmp (fwname,"gpccs_data" )) + legacy_fwname ="fuc41ad" ;
As I mentioned on IRC, I find this strcmp thing a little jarring. It should be pretty easy to just pass the legacy fwname into gf100_gr_ctor_fw directly - there are only a handful of callers, and most would just pass NULL in as the legacy fwname - only the ones in gf100.c would pass the "old" names in.
Otherwise this looks great, thanks for taking care of it!
Quoted 20 lines
drm/nouveau/nvkm/engine/gr/gf100.c +6
-5+ +/* nope, let's just return the error we got */ +if (!legacy_fwname) {nvkm_error (subdev,"failed to load %s\n" , fwname);return ret; } - fuc->size = fw->size; - fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); -nvkm_firmware_put (fw); -return (fuc->data !=NULL ) ?0 : -ENOMEM ; +/* yes, try to load from the legacy path */ +nvkm_debug (subdev,"%s: falling back to legacy path\n" , fwname); +return gf100_gr_ctor_fw_legacy (gr, legacy_fwname, fuc); }int --2.10.0
Quoted 4 lines
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
A message that is not in the archive (sent off-list or not yet received): CAKb7UvhfHs=FJ+3FzkwMgmQfi+uMBvg0kSQ10FpTurRmfDX-cQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Quoted 76 lines · Ilia Mirkin
Quoted 75 lines · Alexandre Courbot
Look for firmware files using the legacy ("nouveau/nvxx_fucxxxx") path if they cannot be found in the new, "official" path. User setups were broken by the switch, which is bad.
There are only 4 firmware files we may want to look up that way, so hardcode them into the lookup function. All new firmware files should use the standard "nvidia/<chip>/gr/" path.
Fixes 8539b37acef7 ("drm/nouveau/gr: use NVIDIA-provided external firmwares")Signed-off-by Alexandre Courbot <[email protected]>--- drm/nouveau/nvkm/engine/gr/gf100.c | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-)drm/nouveau/nvkm/engine/gr/gf100.c +43
-1@@ -1756,24 +1756,70 @@ gf100_gr_ = { };int +gf100_gr_ctor_fw_legacy (struct gf100_gr *gr,const char *fwname, +struct gf100_gr_fuc *fuc) +{ +struct nvkm_subdev *subdev = &gr->base.engine.subdev; +struct nvkm_device *device = subdev->device; +const struct firmware *fw; +char f[32 ]; +int ret; + +snprintf (f,sizeof (f),"nouveau/nv%02x_%s" , device->chipset, fwname); + ret =request_firmware (&fw, f, device->dev); +if (ret) { +snprintf (f,sizeof (f),"nouveau/%s" , fwname); + ret =request_firmware (&fw, f, device->dev); +if (ret) { +nvkm_error (subdev,"failed to load %s\n" , fwname); +return ret; + } + } + + fuc->size = fw->size; + fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); +release_firmware (fw); +return (fuc->data !=NULL ) ?0 : -ENOMEM ; +} + +int gf100_gr_ctor_fw (struct gf100_gr *gr,const char *fwname,struct gf100_gr_fuc *fuc) {struct nvkm_subdev *subdev = &gr->base.engine.subdev;struct nvkm_device *device = subdev->device; +const char *legacy_fwname =NULL ;const struct firmware *fw;int ret; ret =nvkm_firmware_get (device, fwname, &fw); -if (ret) { +/* firmware found, success! */ +if (!ret) { + fuc->size = fw->size; + fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); +nvkm_firmware_put (fw); +return (fuc->data !=NULL ) ?0 : -ENOMEM ; + } + +/* see if this firmware has a legacy path */ +if (!strcmp (fwname,"fecs_inst" )) + legacy_fwname ="fuc409c" ; +else if (!strcmp (fwname,"fecs_data" )) + legacy_fwname ="fuc409d" ; +else if (!strcmp (fwname,"gpccs_inst" )) + legacy_fwname ="fuc41ac" ;
Quoted 8 lines
drm/nouveau/nvkm/engine/gr/gf100.c gf100_gr_ = { · line 1812
Quoted 2 lines
drm/nouveau/nvkm/engine/gr/gf100.c +2
-0+else if (!strcmp (fwname,"gpccs_data" )) + legacy_fwname ="fuc41ad" ;As I mentioned on IRC, I find this strcmp thing a little jarring. It should be pretty easy to just pass the legacy fwname into
gf100_gr_ctor_fwdirectly - there are only a handful of callers, and most would just pass NULL in as the legacy fwname - only the ones ingf100.cwould pass the "old" names in.
Yeah, that was the original approach actually. I switched to this for the following reasons:
- We don't want to encourage using this legacy path, hence hiding it from callers
- There are only 4 possible legacy files - it's ugly but still manageable and contained in a single function
Of course, if the general consensus is that this is too ugly, it would be trivial to turn it the way you suggested, so I don't feel too strongly for one approach over the other.
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
A message that is not in the archive (sent off-list or not yet received): a54062b0-afad-51e8-4d18-9fc84b8e48d8-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org
Quoted 86 lines · Alexandre Courbot
Quoted 76 lines · Ilia Mirkin
Quoted 75 lines · Alexandre Courbot
Look for firmware files using the legacy ("nouveau/nvxx_fucxxxx") path if they cannot be found in the new, "official" path. User setups were broken by the switch, which is bad.
There are only 4 firmware files we may want to look up that way, so hardcode them into the lookup function. All new firmware files should use the standard "nvidia/<chip>/gr/" path.
Fixes 8539b37acef7 ("drm/nouveau/gr: use NVIDIA-provided external firmwares")Signed-off-by Alexandre Courbot <[email protected]>--- drm/nouveau/nvkm/engine/gr/gf100.c | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-)drm/nouveau/nvkm/engine/gr/gf100.c +43
-1@@ -1756,24 +1756,70 @@ gf100_gr_ = { };int +gf100_gr_ctor_fw_legacy (struct gf100_gr *gr,const char *fwname, +struct gf100_gr_fuc *fuc) +{ +struct nvkm_subdev *subdev = &gr->base.engine.subdev; +struct nvkm_device *device = subdev->device; +const struct firmware *fw; +char f[32 ]; +int ret; + +snprintf (f,sizeof (f),"nouveau/nv%02x_%s" , device->chipset, fwname); + ret =request_firmware (&fw, f, device->dev); +if (ret) { +snprintf (f,sizeof (f),"nouveau/%s" , fwname); + ret =request_firmware (&fw, f, device->dev); +if (ret) { +nvkm_error (subdev,"failed to load %s\n" , fwname); +return ret; + } + } + + fuc->size = fw->size; + fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); +release_firmware (fw); +return (fuc->data !=NULL ) ?0 : -ENOMEM ; +} + +int gf100_gr_ctor_fw (struct gf100_gr *gr,const char *fwname,struct gf100_gr_fuc *fuc) {struct nvkm_subdev *subdev = &gr->base.engine.subdev;struct nvkm_device *device = subdev->device; +const char *legacy_fwname =NULL ;const struct firmware *fw;int ret; ret =nvkm_firmware_get (device, fwname, &fw); -if (ret) { +/* firmware found, success! */ +if (!ret) { + fuc->size = fw->size; + fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); +nvkm_firmware_put (fw); +return (fuc->data !=NULL ) ?0 : -ENOMEM ; + } + +/* see if this firmware has a legacy path */ +if (!strcmp (fwname,"fecs_inst" )) + legacy_fwname ="fuc409c" ; +else if (!strcmp (fwname,"fecs_data" )) + legacy_fwname ="fuc409d" ; +else if (!strcmp (fwname,"gpccs_inst" )) + legacy_fwname ="fuc41ac" ;Quoted 8 lines
drm/nouveau/nvkm/engine/gr/gf100.c gf100_gr_ = { · line 1812
Quoted 2 lines
drm/nouveau/nvkm/engine/gr/gf100.c +2
-0+else if (!strcmp (fwname,"gpccs_data" )) + legacy_fwname ="fuc41ad" ;As I mentioned on IRC, I find this strcmp thing a little jarring. It should be pretty easy to just pass the legacy fwname into
gf100_gr_ctor_fwdirectly - there are only a handful of callers, and most would just pass NULL in as the legacy fwname - only the ones ingf100.cwould pass the "old" names in.
Quoted 7 lines
Yeah, that was the original approach actually. I switched to this for the following reasons:
- We don't want to encourage using this legacy path, hence hiding it from callers
- There are only 4 possible legacy files - it's ugly but still manageable and contained in a single function
I agree.
Quoted 4 lines
Of course, if the general consensus is that this is too ugly, it would be trivial to turn it the way you suggested, so I don't feel too strongly for one approach over the other.
As it is a legacy path, I'm more for hiding it away in ctor_legacy() as Emil suggests.
Ben.
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
A message that is not in the archive (sent off-list or not yet received): cc55514d-56aa-6fdf-3f39-92884d4064b9-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
Quoted 96 lines · Ben Skeggs
* PGP Signed by an unknown key
Quoted 86 lines · Alexandre Courbot
Quoted 76 lines · Ilia Mirkin
Quoted 75 lines · Alexandre Courbot
Look for firmware files using the legacy ("nouveau/nvxx_fucxxxx") path if they cannot be found in the new, "official" path. User setups were broken by the switch, which is bad.
There are only 4 firmware files we may want to look up that way, so hardcode them into the lookup function. All new firmware files should use the standard "nvidia/<chip>/gr/" path.
Fixes 8539b37acef7 ("drm/nouveau/gr: use NVIDIA-provided external firmwares")Signed-off-by Alexandre Courbot <[email protected]>--- drm/nouveau/nvkm/engine/gr/gf100.c | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-)drm/nouveau/nvkm/engine/gr/gf100.c +43
-1@@ -1756,24 +1756,70 @@ gf100_gr_ = { };int +gf100_gr_ctor_fw_legacy (struct gf100_gr *gr,const char *fwname, +struct gf100_gr_fuc *fuc) +{ +struct nvkm_subdev *subdev = &gr->base.engine.subdev; +struct nvkm_device *device = subdev->device; +const struct firmware *fw; +char f[32 ]; +int ret; + +snprintf (f,sizeof (f),"nouveau/nv%02x_%s" , device->chipset, fwname); + ret =request_firmware (&fw, f, device->dev); +if (ret) { +snprintf (f,sizeof (f),"nouveau/%s" , fwname); + ret =request_firmware (&fw, f, device->dev); +if (ret) { +nvkm_error (subdev,"failed to load %s\n" , fwname); +return ret; + } + } + + fuc->size = fw->size; + fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); +release_firmware (fw); +return (fuc->data !=NULL ) ?0 : -ENOMEM ; +} + +int gf100_gr_ctor_fw (struct gf100_gr *gr,const char *fwname,struct gf100_gr_fuc *fuc) {struct nvkm_subdev *subdev = &gr->base.engine.subdev;struct nvkm_device *device = subdev->device; +const char *legacy_fwname =NULL ;const struct firmware *fw;int ret; ret =nvkm_firmware_get (device, fwname, &fw); -if (ret) { +/* firmware found, success! */ +if (!ret) { + fuc->size = fw->size; + fuc->data =kmemdup (fw->data, fuc->size,GFP_KERNEL ); +nvkm_firmware_put (fw); +return (fuc->data !=NULL ) ?0 : -ENOMEM ; + } + +/* see if this firmware has a legacy path */ +if (!strcmp (fwname,"fecs_inst" )) + legacy_fwname ="fuc409c" ; +else if (!strcmp (fwname,"fecs_data" )) + legacy_fwname ="fuc409d" ; +else if (!strcmp (fwname,"gpccs_inst" )) + legacy_fwname ="fuc41ac" ;Quoted 8 lines
drm/nouveau/nvkm/engine/gr/gf100.c gf100_gr_ = { · line 1812
Quoted 2 lines
drm/nouveau/nvkm/engine/gr/gf100.c +2
-0+else if (!strcmp (fwname,"gpccs_data" )) + legacy_fwname ="fuc41ad" ;As I mentioned on IRC, I find this strcmp thing a little jarring. It should be pretty easy to just pass the legacy fwname into
gf100_gr_ctor_fwdirectly - there are only a handful of callers, and most would just pass NULL in as the legacy fwname - only the ones ingf100.cwould pass the "old" names in.Quoted 7 lines
Yeah, that was the original approach actually. I switched to this for the following reasons:
- We don't want to encourage using this legacy path, hence hiding it from callers
- There are only 4 possible legacy files - it's ugly but still manageable and contained in a single function
Quoted 8 lines
I agree.
Quoted 4 lines
Of course, if the general consensus is that this is too ugly, it would be trivial to turn it the way you suggested, so I don't feel too strongly for one approach over the other.
As it is a legacy path, I'm more for hiding it away in
ctor_legacy()as Emil suggests.
Makes sense - will respin later today.
Thanks!
Alex.
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
Hi Alex,
drm/nouveau/nvkm/engine/gr/gf100.c gf100_gr_ = { · line 1813
Quoted 10 lines · Alexandre Courbot
drm/nouveau/nvkm/engine/gr/gf100.c +10
-0+/* see if this firmware has a legacy path */ +if (!strcmp (fwname,"fecs_inst" )) + legacy_fwname ="fuc409c" ; +else if (!strcmp (fwname,"fecs_data" )) + legacy_fwname ="fuc409d" ; +else if (!strcmp (fwname,"gpccs_inst" )) + legacy_fwname ="fuc41ac" ; +else if (!strcmp (fwname,"gpccs_data" )) + legacy_fwname ="fuc41ad" ; +
Just an idea: If one's going for this route (and not Ilia's suggestion) it's worth moving this in the legacy function. As-is things look really weird ?
Thanks
Emil
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau