hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/base/firmware_loader/main.c
....@@ -4,7 +4,7 @@
44 *
55 * Copyright (c) 2003 Manuel Estrada Sainz
66 *
7
- * Please see Documentation/firmware_class/ for more information.
7
+ * Please see Documentation/driver-api/firmware/ for more information.
88 *
99 */
1010
....@@ -12,6 +12,7 @@
1212
1313 #include <linux/capability.h>
1414 #include <linux/device.h>
15
+#include <linux/kernel_read_file.h>
1516 #include <linux/module.h>
1617 #include <linux/init.h>
1718 #include <linux/timer.h>
....@@ -33,6 +34,7 @@
3334 #include <linux/syscore_ops.h>
3435 #include <linux/reboot.h>
3536 #include <linux/security.h>
37
+#include <linux/xz.h>
3638
3739 #include <generated/utsrelease.h>
3840
....@@ -163,13 +165,24 @@
163165 return __fw_state_wait_common(fw_priv, MAX_SCHEDULE_TIMEOUT);
164166 }
165167
166
-static int fw_cache_piggyback_on_request(const char *name);
168
+static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv);
167169
168170 static struct fw_priv *__allocate_fw_priv(const char *fw_name,
169171 struct firmware_cache *fwc,
170
- void *dbuf, size_t size)
172
+ void *dbuf,
173
+ size_t size,
174
+ size_t offset,
175
+ u32 opt_flags)
171176 {
172177 struct fw_priv *fw_priv;
178
+
179
+ /* For a partial read, the buffer must be preallocated. */
180
+ if ((opt_flags & FW_OPT_PARTIAL) && !dbuf)
181
+ return NULL;
182
+
183
+ /* Only partial reads are allowed to use an offset. */
184
+ if (offset != 0 && !(opt_flags & FW_OPT_PARTIAL))
185
+ return NULL;
173186
174187 fw_priv = kzalloc(sizeof(*fw_priv), GFP_ATOMIC);
175188 if (!fw_priv)
....@@ -185,6 +198,8 @@
185198 fw_priv->fwc = fwc;
186199 fw_priv->data = dbuf;
187200 fw_priv->allocated_size = size;
201
+ fw_priv->offset = offset;
202
+ fw_priv->opt_flags = opt_flags;
188203 fw_state_init(fw_priv);
189204 #ifdef CONFIG_FW_LOADER_USER_HELPER
190205 INIT_LIST_HEAD(&fw_priv->pending_list);
....@@ -209,13 +224,20 @@
209224 /* Returns 1 for batching firmware requests with the same name */
210225 static int alloc_lookup_fw_priv(const char *fw_name,
211226 struct firmware_cache *fwc,
212
- struct fw_priv **fw_priv, void *dbuf,
213
- size_t size, enum fw_opt opt_flags)
227
+ struct fw_priv **fw_priv,
228
+ void *dbuf,
229
+ size_t size,
230
+ size_t offset,
231
+ u32 opt_flags)
214232 {
215233 struct fw_priv *tmp;
216234
217235 spin_lock(&fwc->lock);
218
- if (!(opt_flags & FW_OPT_NOCACHE)) {
236
+ /*
237
+ * Do not merge requests that are marked to be non-cached or
238
+ * are performing partial reads.
239
+ */
240
+ if (!(opt_flags & (FW_OPT_NOCACHE | FW_OPT_PARTIAL))) {
219241 tmp = __lookup_fw_priv(fw_name);
220242 if (tmp) {
221243 kref_get(&tmp->ref);
....@@ -226,7 +248,7 @@
226248 }
227249 }
228250
229
- tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size);
251
+ tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size, offset, opt_flags);
230252 if (tmp) {
231253 INIT_LIST_HEAD(&tmp->list);
232254 if (!(opt_flags & FW_OPT_NOCACHE))
....@@ -252,17 +274,11 @@
252274 list_del(&fw_priv->list);
253275 spin_unlock(&fwc->lock);
254276
255
-#ifdef CONFIG_FW_LOADER_USER_HELPER
256
- if (fw_priv->is_paged_buf) {
257
- int i;
258
- vunmap(fw_priv->data);
259
- for (i = 0; i < fw_priv->nr_pages; i++)
260
- __free_page(fw_priv->pages[i]);
261
- vfree(fw_priv->pages);
262
- } else
263
-#endif
264
- if (!fw_priv->allocated_size)
277
+ if (fw_is_paged_buf(fw_priv))
278
+ fw_free_paged_buf(fw_priv);
279
+ else if (!fw_priv->allocated_size)
265280 vfree(fw_priv->data);
281
+
266282 kfree_const(fw_priv->fw_name);
267283 kfree(fw_priv);
268284 }
....@@ -274,6 +290,177 @@
274290 if (!kref_put(&fw_priv->ref, __free_fw_priv))
275291 spin_unlock(&fwc->lock);
276292 }
293
+
294
+#ifdef CONFIG_FW_LOADER_PAGED_BUF
295
+bool fw_is_paged_buf(struct fw_priv *fw_priv)
296
+{
297
+ return fw_priv->is_paged_buf;
298
+}
299
+
300
+void fw_free_paged_buf(struct fw_priv *fw_priv)
301
+{
302
+ int i;
303
+
304
+ if (!fw_priv->pages)
305
+ return;
306
+
307
+ vunmap(fw_priv->data);
308
+
309
+ for (i = 0; i < fw_priv->nr_pages; i++)
310
+ __free_page(fw_priv->pages[i]);
311
+ kvfree(fw_priv->pages);
312
+ fw_priv->pages = NULL;
313
+ fw_priv->page_array_size = 0;
314
+ fw_priv->nr_pages = 0;
315
+}
316
+
317
+int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed)
318
+{
319
+ /* If the array of pages is too small, grow it */
320
+ if (fw_priv->page_array_size < pages_needed) {
321
+ int new_array_size = max(pages_needed,
322
+ fw_priv->page_array_size * 2);
323
+ struct page **new_pages;
324
+
325
+ new_pages = kvmalloc_array(new_array_size, sizeof(void *),
326
+ GFP_KERNEL);
327
+ if (!new_pages)
328
+ return -ENOMEM;
329
+ memcpy(new_pages, fw_priv->pages,
330
+ fw_priv->page_array_size * sizeof(void *));
331
+ memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) *
332
+ (new_array_size - fw_priv->page_array_size));
333
+ kvfree(fw_priv->pages);
334
+ fw_priv->pages = new_pages;
335
+ fw_priv->page_array_size = new_array_size;
336
+ }
337
+
338
+ while (fw_priv->nr_pages < pages_needed) {
339
+ fw_priv->pages[fw_priv->nr_pages] =
340
+ alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
341
+
342
+ if (!fw_priv->pages[fw_priv->nr_pages])
343
+ return -ENOMEM;
344
+ fw_priv->nr_pages++;
345
+ }
346
+
347
+ return 0;
348
+}
349
+
350
+int fw_map_paged_buf(struct fw_priv *fw_priv)
351
+{
352
+ /* one pages buffer should be mapped/unmapped only once */
353
+ if (!fw_priv->pages)
354
+ return 0;
355
+
356
+ vunmap(fw_priv->data);
357
+ fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0,
358
+ PAGE_KERNEL_RO);
359
+ if (!fw_priv->data)
360
+ return -ENOMEM;
361
+
362
+ return 0;
363
+}
364
+#endif
365
+
366
+/*
367
+ * XZ-compressed firmware support
368
+ */
369
+#ifdef CONFIG_FW_LOADER_COMPRESS
370
+/* show an error and return the standard error code */
371
+static int fw_decompress_xz_error(struct device *dev, enum xz_ret xz_ret)
372
+{
373
+ if (xz_ret != XZ_STREAM_END) {
374
+ dev_warn(dev, "xz decompression failed (xz_ret=%d)\n", xz_ret);
375
+ return xz_ret == XZ_MEM_ERROR ? -ENOMEM : -EINVAL;
376
+ }
377
+ return 0;
378
+}
379
+
380
+/* single-shot decompression onto the pre-allocated buffer */
381
+static int fw_decompress_xz_single(struct device *dev, struct fw_priv *fw_priv,
382
+ size_t in_size, const void *in_buffer)
383
+{
384
+ struct xz_dec *xz_dec;
385
+ struct xz_buf xz_buf;
386
+ enum xz_ret xz_ret;
387
+
388
+ xz_dec = xz_dec_init(XZ_SINGLE, (u32)-1);
389
+ if (!xz_dec)
390
+ return -ENOMEM;
391
+
392
+ xz_buf.in_size = in_size;
393
+ xz_buf.in = in_buffer;
394
+ xz_buf.in_pos = 0;
395
+ xz_buf.out_size = fw_priv->allocated_size;
396
+ xz_buf.out = fw_priv->data;
397
+ xz_buf.out_pos = 0;
398
+
399
+ xz_ret = xz_dec_run(xz_dec, &xz_buf);
400
+ xz_dec_end(xz_dec);
401
+
402
+ fw_priv->size = xz_buf.out_pos;
403
+ return fw_decompress_xz_error(dev, xz_ret);
404
+}
405
+
406
+/* decompression on paged buffer and map it */
407
+static int fw_decompress_xz_pages(struct device *dev, struct fw_priv *fw_priv,
408
+ size_t in_size, const void *in_buffer)
409
+{
410
+ struct xz_dec *xz_dec;
411
+ struct xz_buf xz_buf;
412
+ enum xz_ret xz_ret;
413
+ struct page *page;
414
+ int err = 0;
415
+
416
+ xz_dec = xz_dec_init(XZ_DYNALLOC, (u32)-1);
417
+ if (!xz_dec)
418
+ return -ENOMEM;
419
+
420
+ xz_buf.in_size = in_size;
421
+ xz_buf.in = in_buffer;
422
+ xz_buf.in_pos = 0;
423
+
424
+ fw_priv->is_paged_buf = true;
425
+ fw_priv->size = 0;
426
+ do {
427
+ if (fw_grow_paged_buf(fw_priv, fw_priv->nr_pages + 1)) {
428
+ err = -ENOMEM;
429
+ goto out;
430
+ }
431
+
432
+ /* decompress onto the new allocated page */
433
+ page = fw_priv->pages[fw_priv->nr_pages - 1];
434
+ xz_buf.out = kmap(page);
435
+ xz_buf.out_pos = 0;
436
+ xz_buf.out_size = PAGE_SIZE;
437
+ xz_ret = xz_dec_run(xz_dec, &xz_buf);
438
+ kunmap(page);
439
+ fw_priv->size += xz_buf.out_pos;
440
+ /* partial decompression means either end or error */
441
+ if (xz_buf.out_pos != PAGE_SIZE)
442
+ break;
443
+ } while (xz_ret == XZ_OK);
444
+
445
+ err = fw_decompress_xz_error(dev, xz_ret);
446
+ if (!err)
447
+ err = fw_map_paged_buf(fw_priv);
448
+
449
+ out:
450
+ xz_dec_end(xz_dec);
451
+ return err;
452
+}
453
+
454
+static int fw_decompress_xz(struct device *dev, struct fw_priv *fw_priv,
455
+ size_t in_size, const void *in_buffer)
456
+{
457
+ /* if the buffer is pre-allocated, we can perform in single-shot mode */
458
+ if (fw_priv->data)
459
+ return fw_decompress_xz_single(dev, fw_priv, in_size, in_buffer);
460
+ else
461
+ return fw_decompress_xz_pages(dev, fw_priv, in_size, in_buffer);
462
+}
463
+#endif /* CONFIG_FW_LOADER_COMPRESS */
277464
278465 /* direct firmware loading support */
279466 static char fw_path_para[256];
....@@ -294,18 +481,23 @@
294481 MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path");
295482
296483 static int
297
-fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv)
484
+fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
485
+ const char *suffix,
486
+ int (*decompress)(struct device *dev,
487
+ struct fw_priv *fw_priv,
488
+ size_t in_size,
489
+ const void *in_buffer))
298490 {
299
- loff_t size;
491
+ size_t size;
300492 int i, len;
301493 int rc = -ENOENT;
302494 char *path;
303
- enum kernel_read_file_id id = READING_FIRMWARE;
304495 size_t msize = INT_MAX;
496
+ void *buffer = NULL;
305497
306498 /* Already populated data member means we're loading into a buffer */
307
- if (fw_priv->data) {
308
- id = READING_FIRMWARE_PREALLOC_BUFFER;
499
+ if (!decompress && fw_priv->data) {
500
+ buffer = fw_priv->data;
309501 msize = fw_priv->allocated_size;
310502 }
311503
....@@ -314,31 +506,66 @@
314506 return -ENOMEM;
315507
316508 for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
509
+ size_t file_size = 0;
510
+ size_t *file_size_ptr = NULL;
511
+
317512 /* skip the unset customized path */
318513 if (!fw_path[i][0])
319514 continue;
320515
321
- len = snprintf(path, PATH_MAX, "%s/%s",
322
- fw_path[i], fw_priv->fw_name);
516
+ len = snprintf(path, PATH_MAX, "%s/%s%s",
517
+ fw_path[i], fw_priv->fw_name, suffix);
323518 if (len >= PATH_MAX) {
324519 rc = -ENAMETOOLONG;
325520 break;
326521 }
327522
328523 fw_priv->size = 0;
329
- rc = kernel_read_file_from_path(path, &fw_priv->data, &size,
330
- msize, id);
331
- if (rc) {
332
- if (rc == -ENOENT)
333
- dev_dbg(device, "loading %s failed with error %d\n",
334
- path, rc);
335
- else
524
+
525
+ /*
526
+ * The total file size is only examined when doing a partial
527
+ * read; the "full read" case needs to fail if the whole
528
+ * firmware was not completely loaded.
529
+ */
530
+ if ((fw_priv->opt_flags & FW_OPT_PARTIAL) && buffer)
531
+ file_size_ptr = &file_size;
532
+
533
+ /* load firmware files from the mount namespace of init */
534
+ rc = kernel_read_file_from_path_initns(path, fw_priv->offset,
535
+ &buffer, msize,
536
+ file_size_ptr,
537
+ READING_FIRMWARE);
538
+ if (rc < 0) {
539
+ if (rc != -ENOENT)
336540 dev_warn(device, "loading %s failed with error %d\n",
337541 path, rc);
542
+ else
543
+ dev_dbg(device, "loading %s failed for no such file or directory.\n",
544
+ path);
338545 continue;
339546 }
340
- dev_dbg(device, "direct-loading %s\n", fw_priv->fw_name);
341
- fw_priv->size = size;
547
+ size = rc;
548
+ rc = 0;
549
+
550
+ dev_dbg(device, "Loading firmware from %s\n", path);
551
+ if (decompress) {
552
+ dev_dbg(device, "f/w decompressing %s\n",
553
+ fw_priv->fw_name);
554
+ rc = decompress(device, fw_priv, size, buffer);
555
+ /* discard the superfluous original content */
556
+ vfree(buffer);
557
+ buffer = NULL;
558
+ if (rc) {
559
+ fw_free_paged_buf(fw_priv);
560
+ continue;
561
+ }
562
+ } else {
563
+ dev_dbg(device, "direct-loading %s\n",
564
+ fw_priv->fw_name);
565
+ if (!fw_priv->data)
566
+ fw_priv->data = buffer;
567
+ fw_priv->size = size;
568
+ }
342569 fw_state_done(fw_priv);
343570 break;
344571 }
....@@ -362,9 +589,6 @@
362589 static void fw_set_page_data(struct fw_priv *fw_priv, struct firmware *fw)
363590 {
364591 fw->priv = fw_priv;
365
-#ifdef CONFIG_FW_LOADER_USER_HELPER
366
- fw->pages = fw_priv->pages;
367
-#endif
368592 fw->size = fw_priv->size;
369593 fw->data = fw_priv->data;
370594
....@@ -449,8 +673,7 @@
449673 }
450674 #endif
451675
452
-int assign_fw(struct firmware *fw, struct device *device,
453
- enum fw_opt opt_flags)
676
+int assign_fw(struct firmware *fw, struct device *device)
454677 {
455678 struct fw_priv *fw_priv = fw->priv;
456679 int ret;
....@@ -469,8 +692,8 @@
469692 * should be fixed in devres or driver core.
470693 */
471694 /* don't cache firmware handled without uevent */
472
- if (device && (opt_flags & FW_OPT_UEVENT) &&
473
- !(opt_flags & FW_OPT_NOCACHE)) {
695
+ if (device && (fw_priv->opt_flags & FW_OPT_UEVENT) &&
696
+ !(fw_priv->opt_flags & FW_OPT_NOCACHE)) {
474697 ret = fw_add_devm_name(device, fw_priv->fw_name);
475698 if (ret) {
476699 mutex_unlock(&fw_lock);
....@@ -482,11 +705,9 @@
482705 * After caching firmware image is started, let it piggyback
483706 * on request firmware.
484707 */
485
- if (!(opt_flags & FW_OPT_NOCACHE) &&
486
- fw_priv->fwc->state == FW_LOADER_START_CACHE) {
487
- if (fw_cache_piggyback_on_request(fw_priv->fw_name))
488
- kref_get(&fw_priv->ref);
489
- }
708
+ if (!(fw_priv->opt_flags & FW_OPT_NOCACHE) &&
709
+ fw_priv->fwc->state == FW_LOADER_START_CACHE)
710
+ fw_cache_piggyback_on_request(fw_priv);
490711
491712 /* pass the pages buffer to driver at the last minute */
492713 fw_set_page_data(fw_priv, fw);
....@@ -501,7 +722,7 @@
501722 static int
502723 _request_firmware_prepare(struct firmware **firmware_p, const char *name,
503724 struct device *device, void *dbuf, size_t size,
504
- enum fw_opt opt_flags)
725
+ size_t offset, u32 opt_flags)
505726 {
506727 struct firmware *firmware;
507728 struct fw_priv *fw_priv;
....@@ -520,7 +741,7 @@
520741 }
521742
522743 ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size,
523
- opt_flags);
744
+ offset, opt_flags);
524745
525746 /*
526747 * bind with 'priv' now to avoid warning in failure path
....@@ -569,9 +790,10 @@
569790 static int
570791 _request_firmware(const struct firmware **firmware_p, const char *name,
571792 struct device *device, void *buf, size_t size,
572
- enum fw_opt opt_flags)
793
+ size_t offset, u32 opt_flags)
573794 {
574795 struct firmware *fw = NULL;
796
+ bool nondirect = false;
575797 int ret;
576798
577799 if (!firmware_p)
....@@ -583,19 +805,34 @@
583805 }
584806
585807 ret = _request_firmware_prepare(&fw, name, device, buf, size,
586
- opt_flags);
808
+ offset, opt_flags);
587809 if (ret <= 0) /* error or already assigned */
588810 goto out;
589811
590
- ret = fw_get_filesystem_firmware(device, fw->priv);
812
+ ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);
813
+
814
+ /* Only full reads can support decompression, platform, and sysfs. */
815
+ if (!(opt_flags & FW_OPT_PARTIAL))
816
+ nondirect = true;
817
+
818
+#ifdef CONFIG_FW_LOADER_COMPRESS
819
+ if (ret == -ENOENT && nondirect)
820
+ ret = fw_get_filesystem_firmware(device, fw->priv, ".xz",
821
+ fw_decompress_xz);
822
+#endif
823
+ if (ret == -ENOENT && nondirect)
824
+ ret = firmware_fallback_platform(fw->priv);
825
+
591826 if (ret) {
592827 if (!(opt_flags & FW_OPT_NO_WARN))
593828 dev_warn(device,
594829 "Direct firmware load for %s failed with error %d\n",
595830 name, ret);
596
- ret = firmware_fallback_sysfs(fw, name, device, opt_flags, ret);
831
+ if (nondirect)
832
+ ret = firmware_fallback_sysfs(fw, name, device,
833
+ opt_flags, ret);
597834 } else
598
- ret = assign_fw(fw, device, opt_flags);
835
+ ret = assign_fw(fw, device);
599836
600837 out:
601838 if (ret < 0) {
....@@ -636,7 +873,7 @@
636873
637874 /* Need to pin this module until return */
638875 __module_get(THIS_MODULE);
639
- ret = _request_firmware(firmware_p, name, device, NULL, 0,
876
+ ret = _request_firmware(firmware_p, name, device, NULL, 0, 0,
640877 FW_OPT_UEVENT);
641878 module_put(THIS_MODULE);
642879 return ret;
....@@ -649,12 +886,12 @@
649886 * @name: name of firmware file
650887 * @device: device for which firmware is being loaded
651888 *
652
- * This function is similar in behaviour to request_firmware(), except
653
- * it doesn't produce warning messages when the file is not found.
654
- * The sysfs fallback mechanism is enabled if direct filesystem lookup fails,
655
- * however, however failures to find the firmware file with it are still
656
- * suppressed. It is therefore up to the driver to check for the return value
657
- * of this call and to decide when to inform the users of errors.
889
+ * This function is similar in behaviour to request_firmware(), except it
890
+ * doesn't produce warning messages when the file is not found. The sysfs
891
+ * fallback mechanism is enabled if direct filesystem lookup fails. However,
892
+ * failures to find the firmware file with it are still suppressed. It is
893
+ * therefore up to the driver to check for the return value of this call and to
894
+ * decide when to inform the users of errors.
658895 **/
659896 int firmware_request_nowarn(const struct firmware **firmware, const char *name,
660897 struct device *device)
....@@ -663,7 +900,7 @@
663900
664901 /* Need to pin this module until return */
665902 __module_get(THIS_MODULE);
666
- ret = _request_firmware(firmware, name, device, NULL, 0,
903
+ ret = _request_firmware(firmware, name, device, NULL, 0, 0,
667904 FW_OPT_UEVENT | FW_OPT_NO_WARN);
668905 module_put(THIS_MODULE);
669906 return ret;
....@@ -687,13 +924,37 @@
687924 int ret;
688925
689926 __module_get(THIS_MODULE);
690
- ret = _request_firmware(firmware_p, name, device, NULL, 0,
927
+ ret = _request_firmware(firmware_p, name, device, NULL, 0, 0,
691928 FW_OPT_UEVENT | FW_OPT_NO_WARN |
692
- FW_OPT_NOFALLBACK);
929
+ FW_OPT_NOFALLBACK_SYSFS);
693930 module_put(THIS_MODULE);
694931 return ret;
695932 }
696933 EXPORT_SYMBOL_GPL(request_firmware_direct);
934
+
935
+/**
936
+ * firmware_request_platform() - request firmware with platform-fw fallback
937
+ * @firmware: pointer to firmware image
938
+ * @name: name of firmware file
939
+ * @device: device for which firmware is being loaded
940
+ *
941
+ * This function is similar in behaviour to request_firmware, except that if
942
+ * direct filesystem lookup fails, it will fallback to looking for a copy of the
943
+ * requested firmware embedded in the platform's main (e.g. UEFI) firmware.
944
+ **/
945
+int firmware_request_platform(const struct firmware **firmware,
946
+ const char *name, struct device *device)
947
+{
948
+ int ret;
949
+
950
+ /* Need to pin this module until return */
951
+ __module_get(THIS_MODULE);
952
+ ret = _request_firmware(firmware, name, device, NULL, 0, 0,
953
+ FW_OPT_UEVENT | FW_OPT_FALLBACK_PLATFORM);
954
+ module_put(THIS_MODULE);
955
+ return ret;
956
+}
957
+EXPORT_SYMBOL_GPL(firmware_request_platform);
697958
698959 /**
699960 * firmware_request_cache() - cache firmware for suspend so resume can use it
....@@ -744,12 +1005,43 @@
7441005 return -EOPNOTSUPP;
7451006
7461007 __module_get(THIS_MODULE);
747
- ret = _request_firmware(firmware_p, name, device, buf, size,
1008
+ ret = _request_firmware(firmware_p, name, device, buf, size, 0,
7481009 FW_OPT_UEVENT | FW_OPT_NOCACHE);
7491010 module_put(THIS_MODULE);
7501011 return ret;
7511012 }
7521013 EXPORT_SYMBOL(request_firmware_into_buf);
1014
+
1015
+/**
1016
+ * request_partial_firmware_into_buf() - load partial firmware into a previously allocated buffer
1017
+ * @firmware_p: pointer to firmware image
1018
+ * @name: name of firmware file
1019
+ * @device: device for which firmware is being loaded and DMA region allocated
1020
+ * @buf: address of buffer to load firmware into
1021
+ * @size: size of buffer
1022
+ * @offset: offset into file to read
1023
+ *
1024
+ * This function works pretty much like request_firmware_into_buf except
1025
+ * it allows a partial read of the file.
1026
+ */
1027
+int
1028
+request_partial_firmware_into_buf(const struct firmware **firmware_p,
1029
+ const char *name, struct device *device,
1030
+ void *buf, size_t size, size_t offset)
1031
+{
1032
+ int ret;
1033
+
1034
+ if (fw_cache_is_setup(device, name))
1035
+ return -EOPNOTSUPP;
1036
+
1037
+ __module_get(THIS_MODULE);
1038
+ ret = _request_firmware(firmware_p, name, device, buf, size, offset,
1039
+ FW_OPT_UEVENT | FW_OPT_NOCACHE |
1040
+ FW_OPT_PARTIAL);
1041
+ module_put(THIS_MODULE);
1042
+ return ret;
1043
+}
1044
+EXPORT_SYMBOL(request_partial_firmware_into_buf);
7531045
7541046 /**
7551047 * release_firmware() - release the resource associated with a firmware image
....@@ -773,7 +1065,7 @@
7731065 struct device *device;
7741066 void *context;
7751067 void (*cont)(const struct firmware *fw, void *context);
776
- enum fw_opt opt_flags;
1068
+ u32 opt_flags;
7771069 };
7781070
7791071 static void request_firmware_work_func(struct work_struct *work)
....@@ -783,7 +1075,7 @@
7831075
7841076 fw_work = container_of(work, struct firmware_work, work);
7851077
786
- _request_firmware(&fw, fw_work->name, fw_work->device, NULL, 0,
1078
+ _request_firmware(&fw, fw_work->name, fw_work->device, NULL, 0, 0,
7871079 fw_work->opt_flags);
7881080 fw_work->cont(fw, fw_work->context);
7891081 put_device(fw_work->device); /* taken in request_firmware_nowait() */
....@@ -964,11 +1256,11 @@
9641256 return 0;
9651257 }
9661258
967
-static int fw_cache_piggyback_on_request(const char *name)
1259
+static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv)
9681260 {
969
- struct firmware_cache *fwc = &fw_cache;
1261
+ const char *name = fw_priv->fw_name;
1262
+ struct firmware_cache *fwc = fw_priv->fwc;
9701263 struct fw_cache_entry *fce;
971
- int ret = 0;
9721264
9731265 spin_lock(&fwc->name_lock);
9741266 if (__fw_entry_found(name))
....@@ -976,13 +1268,12 @@
9761268
9771269 fce = alloc_fw_cache_entry(name);
9781270 if (fce) {
979
- ret = 1;
9801271 list_add(&fce->list, &fwc->fw_names);
1272
+ kref_get(&fw_priv->ref);
9811273 pr_debug("%s: fw: %s\n", __func__, name);
9821274 }
9831275 found:
9841276 spin_unlock(&fwc->name_lock);
985
- return ret;
9861277 }
9871278
9881279 static void free_fw_cache_entry(struct fw_cache_entry *fce)
....@@ -1213,9 +1504,8 @@
12131504 unregister_pm_notifier(&fw_cache.pm_notify);
12141505 }
12151506 #else
1216
-static int fw_cache_piggyback_on_request(const char *name)
1507
+static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv)
12171508 {
1218
- return 0;
12191509 }
12201510 static inline int register_fw_pm_ops(void)
12211511 {