main.c (1136fa0c07de570dc17858745af8be169d1440ba) main.c (23cfbc6ec44e5e80d5522976ff45ffcdcddfb230)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * main.c - Multi purpose firmware loading support
4 *
5 * Copyright (c) 2003 Manuel Estrada Sainz
6 *
7 * Please see Documentation/driver-api/firmware/ for more information.
8 *

--- 21 unchanged lines hidden (view full) ---

30#include <linux/list.h>
31#include <linux/fs.h>
32#include <linux/async.h>
33#include <linux/pm.h>
34#include <linux/suspend.h>
35#include <linux/syscore_ops.h>
36#include <linux/reboot.h>
37#include <linux/security.h>
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * main.c - Multi purpose firmware loading support
4 *
5 * Copyright (c) 2003 Manuel Estrada Sainz
6 *
7 * Please see Documentation/driver-api/firmware/ for more information.
8 *

--- 21 unchanged lines hidden (view full) ---

30#include <linux/list.h>
31#include <linux/fs.h>
32#include <linux/async.h>
33#include <linux/pm.h>
34#include <linux/suspend.h>
35#include <linux/syscore_ops.h>
36#include <linux/reboot.h>
37#include <linux/security.h>
38#include <linux/zstd.h>
38#include <linux/xz.h>
39
40#include <generated/utsrelease.h>
41
42#include "../base.h"
43#include "firmware.h"
44#include "fallback.h"
45

--- 254 unchanged lines hidden (view full) ---

300 if (!fw_priv->data)
301 return -ENOMEM;
302
303 return 0;
304}
305#endif
306
307/*
39#include <linux/xz.h>
40
41#include <generated/utsrelease.h>
42
43#include "../base.h"
44#include "firmware.h"
45#include "fallback.h"
46

--- 254 unchanged lines hidden (view full) ---

301 if (!fw_priv->data)
302 return -ENOMEM;
303
304 return 0;
305}
306#endif
307
308/*
309 * ZSTD-compressed firmware support
310 */
311#ifdef CONFIG_FW_LOADER_COMPRESS_ZSTD
312static int fw_decompress_zstd(struct device *dev, struct fw_priv *fw_priv,
313 size_t in_size, const void *in_buffer)
314{
315 size_t len, out_size, workspace_size;
316 void *workspace, *out_buf;
317 zstd_dctx *ctx;
318 int err;
319
320 if (fw_priv->allocated_size) {
321 out_size = fw_priv->allocated_size;
322 out_buf = fw_priv->data;
323 } else {
324 zstd_frame_header params;
325
326 if (zstd_get_frame_header(&params, in_buffer, in_size) ||
327 params.frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) {
328 dev_dbg(dev, "%s: invalid zstd header\n", __func__);
329 return -EINVAL;
330 }
331 out_size = params.frameContentSize;
332 out_buf = vzalloc(out_size);
333 if (!out_buf)
334 return -ENOMEM;
335 }
336
337 workspace_size = zstd_dctx_workspace_bound();
338 workspace = kvzalloc(workspace_size, GFP_KERNEL);
339 if (!workspace) {
340 err = -ENOMEM;
341 goto error;
342 }
343
344 ctx = zstd_init_dctx(workspace, workspace_size);
345 if (!ctx) {
346 dev_dbg(dev, "%s: failed to initialize context\n", __func__);
347 err = -EINVAL;
348 goto error;
349 }
350
351 len = zstd_decompress_dctx(ctx, out_buf, out_size, in_buffer, in_size);
352 if (zstd_is_error(len)) {
353 dev_dbg(dev, "%s: failed to decompress: %d\n", __func__,
354 zstd_get_error_code(len));
355 err = -EINVAL;
356 goto error;
357 }
358
359 if (!fw_priv->allocated_size)
360 fw_priv->data = out_buf;
361 fw_priv->size = len;
362 err = 0;
363
364 error:
365 kvfree(workspace);
366 if (err && !fw_priv->allocated_size)
367 vfree(out_buf);
368 return err;
369}
370#endif /* CONFIG_FW_LOADER_COMPRESS_ZSTD */
371
372/*
308 * XZ-compressed firmware support
309 */
373 * XZ-compressed firmware support
374 */
310#ifdef CONFIG_FW_LOADER_COMPRESS
375#ifdef CONFIG_FW_LOADER_COMPRESS_XZ
311/* show an error and return the standard error code */
312static int fw_decompress_xz_error(struct device *dev, enum xz_ret xz_ret)
313{
314 if (xz_ret != XZ_STREAM_END) {
315 dev_warn(dev, "xz decompression failed (xz_ret=%d)\n", xz_ret);
316 return xz_ret == XZ_MEM_ERROR ? -ENOMEM : -EINVAL;
317 }
318 return 0;

--- 77 unchanged lines hidden (view full) ---

396 size_t in_size, const void *in_buffer)
397{
398 /* if the buffer is pre-allocated, we can perform in single-shot mode */
399 if (fw_priv->data)
400 return fw_decompress_xz_single(dev, fw_priv, in_size, in_buffer);
401 else
402 return fw_decompress_xz_pages(dev, fw_priv, in_size, in_buffer);
403}
376/* show an error and return the standard error code */
377static int fw_decompress_xz_error(struct device *dev, enum xz_ret xz_ret)
378{
379 if (xz_ret != XZ_STREAM_END) {
380 dev_warn(dev, "xz decompression failed (xz_ret=%d)\n", xz_ret);
381 return xz_ret == XZ_MEM_ERROR ? -ENOMEM : -EINVAL;
382 }
383 return 0;

--- 77 unchanged lines hidden (view full) ---

461 size_t in_size, const void *in_buffer)
462{
463 /* if the buffer is pre-allocated, we can perform in single-shot mode */
464 if (fw_priv->data)
465 return fw_decompress_xz_single(dev, fw_priv, in_size, in_buffer);
466 else
467 return fw_decompress_xz_pages(dev, fw_priv, in_size, in_buffer);
468}
404#endif /* CONFIG_FW_LOADER_COMPRESS */
469#endif /* CONFIG_FW_LOADER_COMPRESS_XZ */
405
406/* direct firmware loading support */
407static char fw_path_para[256];
408static const char * const fw_path[] = {
409 fw_path_para,
410 "/lib/firmware/updates/" UTS_RELEASE,
411 "/lib/firmware/updates",
412 "/lib/firmware/" UTS_RELEASE,

--- 339 unchanged lines hidden (view full) ---

752 goto out;
753
754 ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);
755
756 /* Only full reads can support decompression, platform, and sysfs. */
757 if (!(opt_flags & FW_OPT_PARTIAL))
758 nondirect = true;
759
470
471/* direct firmware loading support */
472static char fw_path_para[256];
473static const char * const fw_path[] = {
474 fw_path_para,
475 "/lib/firmware/updates/" UTS_RELEASE,
476 "/lib/firmware/updates",
477 "/lib/firmware/" UTS_RELEASE,

--- 339 unchanged lines hidden (view full) ---

817 goto out;
818
819 ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);
820
821 /* Only full reads can support decompression, platform, and sysfs. */
822 if (!(opt_flags & FW_OPT_PARTIAL))
823 nondirect = true;
824
760#ifdef CONFIG_FW_LOADER_COMPRESS
825#ifdef CONFIG_FW_LOADER_COMPRESS_ZSTD
761 if (ret == -ENOENT && nondirect)
826 if (ret == -ENOENT && nondirect)
827 ret = fw_get_filesystem_firmware(device, fw->priv, ".zst",
828 fw_decompress_zstd);
829#endif
830#ifdef CONFIG_FW_LOADER_COMPRESS_XZ
831 if (ret == -ENOENT && nondirect)
762 ret = fw_get_filesystem_firmware(device, fw->priv, ".xz",
763 fw_decompress_xz);
764#endif
765 if (ret == -ENOENT && nondirect)
766 ret = firmware_fallback_platform(fw->priv);
767
768 if (ret) {
769 if (!(opt_flags & FW_OPT_NO_WARN))

--- 745 unchanged lines hidden ---
832 ret = fw_get_filesystem_firmware(device, fw->priv, ".xz",
833 fw_decompress_xz);
834#endif
835 if (ret == -ENOENT && nondirect)
836 ret = firmware_fallback_platform(fw->priv);
837
838 if (ret) {
839 if (!(opt_flags & FW_OPT_NO_WARN))

--- 745 unchanged lines hidden ---