@@ -170,10 +170,19 @@ static struct fw_priv *__allocate_fw_priv(const char *fw_name,
170
170
struct firmware_cache * fwc ,
171
171
void * dbuf ,
172
172
size_t size ,
173
+ size_t offset ,
173
174
u32 opt_flags )
174
175
{
175
176
struct fw_priv * fw_priv ;
176
177
178
+ /* For a partial read, the buffer must be preallocated. */
179
+ if ((opt_flags & FW_OPT_PARTIAL ) && !dbuf )
180
+ return NULL ;
181
+
182
+ /* Only partial reads are allowed to use an offset. */
183
+ if (offset != 0 && !(opt_flags & FW_OPT_PARTIAL ))
184
+ return NULL ;
185
+
177
186
fw_priv = kzalloc (sizeof (* fw_priv ), GFP_ATOMIC );
178
187
if (!fw_priv )
179
188
return NULL ;
@@ -188,6 +197,7 @@ static struct fw_priv *__allocate_fw_priv(const char *fw_name,
188
197
fw_priv -> fwc = fwc ;
189
198
fw_priv -> data = dbuf ;
190
199
fw_priv -> allocated_size = size ;
200
+ fw_priv -> offset = offset ;
191
201
fw_priv -> opt_flags = opt_flags ;
192
202
fw_state_init (fw_priv );
193
203
#ifdef CONFIG_FW_LOADER_USER_HELPER
@@ -216,12 +226,17 @@ static int alloc_lookup_fw_priv(const char *fw_name,
216
226
struct fw_priv * * fw_priv ,
217
227
void * dbuf ,
218
228
size_t size ,
229
+ size_t offset ,
219
230
u32 opt_flags )
220
231
{
221
232
struct fw_priv * tmp ;
222
233
223
234
spin_lock (& fwc -> lock );
224
- if (!(opt_flags & FW_OPT_NOCACHE )) {
235
+ /*
236
+ * Do not merge requests that are marked to be non-cached or
237
+ * are performing partial reads.
238
+ */
239
+ if (!(opt_flags & (FW_OPT_NOCACHE | FW_OPT_PARTIAL ))) {
225
240
tmp = __lookup_fw_priv (fw_name );
226
241
if (tmp ) {
227
242
kref_get (& tmp -> ref );
@@ -232,7 +247,7 @@ static int alloc_lookup_fw_priv(const char *fw_name,
232
247
}
233
248
}
234
249
235
- tmp = __allocate_fw_priv (fw_name , fwc , dbuf , size , opt_flags );
250
+ tmp = __allocate_fw_priv (fw_name , fwc , dbuf , size , offset , opt_flags );
236
251
if (tmp ) {
237
252
INIT_LIST_HEAD (& tmp -> list );
238
253
if (!(opt_flags & FW_OPT_NOCACHE ))
@@ -490,6 +505,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
490
505
return - ENOMEM ;
491
506
492
507
for (i = 0 ; i < ARRAY_SIZE (fw_path ); i ++ ) {
508
+ size_t file_size = 0 ;
509
+ size_t * file_size_ptr = NULL ;
510
+
493
511
/* skip the unset customized path */
494
512
if (!fw_path [i ][0 ])
495
513
continue ;
@@ -503,9 +521,18 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
503
521
504
522
fw_priv -> size = 0 ;
505
523
524
+ /*
525
+ * The total file size is only examined when doing a partial
526
+ * read; the "full read" case needs to fail if the whole
527
+ * firmware was not completely loaded.
528
+ */
529
+ if ((fw_priv -> opt_flags & FW_OPT_PARTIAL ) && buffer )
530
+ file_size_ptr = & file_size ;
531
+
506
532
/* load firmware files from the mount namespace of init */
507
- rc = kernel_read_file_from_path_initns (path , 0 , & buffer , msize ,
508
- NULL ,
533
+ rc = kernel_read_file_from_path_initns (path , fw_priv -> offset ,
534
+ & buffer , msize ,
535
+ file_size_ptr ,
509
536
READING_FIRMWARE );
510
537
if (rc < 0 ) {
511
538
if (rc != - ENOENT )
@@ -696,7 +723,7 @@ int assign_fw(struct firmware *fw, struct device *device)
696
723
static int
697
724
_request_firmware_prepare (struct firmware * * firmware_p , const char * name ,
698
725
struct device * device , void * dbuf , size_t size ,
699
- u32 opt_flags )
726
+ size_t offset , u32 opt_flags )
700
727
{
701
728
struct firmware * firmware ;
702
729
struct fw_priv * fw_priv ;
@@ -715,7 +742,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
715
742
}
716
743
717
744
ret = alloc_lookup_fw_priv (name , & fw_cache , & fw_priv , dbuf , size ,
718
- opt_flags );
745
+ offset , opt_flags );
719
746
720
747
/*
721
748
* bind with 'priv' now to avoid warning in failure path
@@ -762,9 +789,10 @@ static void fw_abort_batch_reqs(struct firmware *fw)
762
789
static int
763
790
_request_firmware (const struct firmware * * firmware_p , const char * name ,
764
791
struct device * device , void * buf , size_t size ,
765
- u32 opt_flags )
792
+ size_t offset , u32 opt_flags )
766
793
{
767
794
struct firmware * fw = NULL ;
795
+ bool nondirect = false;
768
796
int ret ;
769
797
770
798
if (!firmware_p )
@@ -776,26 +804,32 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
776
804
}
777
805
778
806
ret = _request_firmware_prepare (& fw , name , device , buf , size ,
779
- opt_flags );
807
+ offset , opt_flags );
780
808
if (ret <= 0 ) /* error or already assigned */
781
809
goto out ;
782
810
783
811
ret = fw_get_filesystem_firmware (device , fw -> priv , "" , NULL );
812
+
813
+ /* Only full reads can support decompression, platform, and sysfs. */
814
+ if (!(opt_flags & FW_OPT_PARTIAL ))
815
+ nondirect = true;
816
+
784
817
#ifdef CONFIG_FW_LOADER_COMPRESS
785
- if (ret == - ENOENT )
818
+ if (ret == - ENOENT && nondirect )
786
819
ret = fw_get_filesystem_firmware (device , fw -> priv , ".xz" ,
787
820
fw_decompress_xz );
788
821
#endif
789
-
790
- if (ret == - ENOENT )
822
+ if (ret == - ENOENT && nondirect )
791
823
ret = firmware_fallback_platform (fw -> priv );
792
824
793
825
if (ret ) {
794
826
if (!(opt_flags & FW_OPT_NO_WARN ))
795
827
dev_warn (device ,
796
828
"Direct firmware load for %s failed with error %d\n" ,
797
829
name , ret );
798
- ret = firmware_fallback_sysfs (fw , name , device , opt_flags , ret );
830
+ if (nondirect )
831
+ ret = firmware_fallback_sysfs (fw , name , device ,
832
+ opt_flags , ret );
799
833
} else
800
834
ret = assign_fw (fw , device );
801
835
@@ -838,7 +872,7 @@ request_firmware(const struct firmware **firmware_p, const char *name,
838
872
839
873
/* Need to pin this module until return */
840
874
__module_get (THIS_MODULE );
841
- ret = _request_firmware (firmware_p , name , device , NULL , 0 ,
875
+ ret = _request_firmware (firmware_p , name , device , NULL , 0 , 0 ,
842
876
FW_OPT_UEVENT );
843
877
module_put (THIS_MODULE );
844
878
return ret ;
@@ -865,7 +899,7 @@ int firmware_request_nowarn(const struct firmware **firmware, const char *name,
865
899
866
900
/* Need to pin this module until return */
867
901
__module_get (THIS_MODULE );
868
- ret = _request_firmware (firmware , name , device , NULL , 0 ,
902
+ ret = _request_firmware (firmware , name , device , NULL , 0 , 0 ,
869
903
FW_OPT_UEVENT | FW_OPT_NO_WARN );
870
904
module_put (THIS_MODULE );
871
905
return ret ;
@@ -889,7 +923,7 @@ int request_firmware_direct(const struct firmware **firmware_p,
889
923
int ret ;
890
924
891
925
__module_get (THIS_MODULE );
892
- ret = _request_firmware (firmware_p , name , device , NULL , 0 ,
926
+ ret = _request_firmware (firmware_p , name , device , NULL , 0 , 0 ,
893
927
FW_OPT_UEVENT | FW_OPT_NO_WARN |
894
928
FW_OPT_NOFALLBACK_SYSFS );
895
929
module_put (THIS_MODULE );
@@ -914,7 +948,7 @@ int firmware_request_platform(const struct firmware **firmware,
914
948
915
949
/* Need to pin this module until return */
916
950
__module_get (THIS_MODULE );
917
- ret = _request_firmware (firmware , name , device , NULL , 0 ,
951
+ ret = _request_firmware (firmware , name , device , NULL , 0 , 0 ,
918
952
FW_OPT_UEVENT | FW_OPT_FALLBACK_PLATFORM );
919
953
module_put (THIS_MODULE );
920
954
return ret ;
@@ -970,13 +1004,44 @@ request_firmware_into_buf(const struct firmware **firmware_p, const char *name,
970
1004
return - EOPNOTSUPP ;
971
1005
972
1006
__module_get (THIS_MODULE );
973
- ret = _request_firmware (firmware_p , name , device , buf , size ,
1007
+ ret = _request_firmware (firmware_p , name , device , buf , size , 0 ,
974
1008
FW_OPT_UEVENT | FW_OPT_NOCACHE );
975
1009
module_put (THIS_MODULE );
976
1010
return ret ;
977
1011
}
978
1012
EXPORT_SYMBOL (request_firmware_into_buf );
979
1013
1014
+ /**
1015
+ * request_partial_firmware_into_buf() - load partial firmware into a previously allocated buffer
1016
+ * @firmware_p: pointer to firmware image
1017
+ * @name: name of firmware file
1018
+ * @device: device for which firmware is being loaded and DMA region allocated
1019
+ * @buf: address of buffer to load firmware into
1020
+ * @size: size of buffer
1021
+ * @offset: offset into file to read
1022
+ *
1023
+ * This function works pretty much like request_firmware_into_buf except
1024
+ * it allows a partial read of the file.
1025
+ */
1026
+ int
1027
+ request_partial_firmware_into_buf (const struct firmware * * firmware_p ,
1028
+ const char * name , struct device * device ,
1029
+ void * buf , size_t size , size_t offset )
1030
+ {
1031
+ int ret ;
1032
+
1033
+ if (fw_cache_is_setup (device , name ))
1034
+ return - EOPNOTSUPP ;
1035
+
1036
+ __module_get (THIS_MODULE );
1037
+ ret = _request_firmware (firmware_p , name , device , buf , size , offset ,
1038
+ FW_OPT_UEVENT | FW_OPT_NOCACHE |
1039
+ FW_OPT_PARTIAL );
1040
+ module_put (THIS_MODULE );
1041
+ return ret ;
1042
+ }
1043
+ EXPORT_SYMBOL (request_partial_firmware_into_buf );
1044
+
980
1045
/**
981
1046
* release_firmware() - release the resource associated with a firmware image
982
1047
* @fw: firmware resource to release
@@ -1009,7 +1074,7 @@ static void request_firmware_work_func(struct work_struct *work)
1009
1074
1010
1075
fw_work = container_of (work , struct firmware_work , work );
1011
1076
1012
- _request_firmware (& fw , fw_work -> name , fw_work -> device , NULL , 0 ,
1077
+ _request_firmware (& fw , fw_work -> name , fw_work -> device , NULL , 0 , 0 ,
1013
1078
fw_work -> opt_flags );
1014
1079
fw_work -> cont (fw , fw_work -> context );
1015
1080
put_device (fw_work -> device ); /* taken in request_firmware_nowait() */
0 commit comments