Lines Matching defs:fw_priv
81 static inline struct fw_priv *to_fw_priv(struct kref *ref)
83 return container_of(ref, struct fw_priv, ref);
155 static void fw_state_init(struct fw_priv *fw_priv)
157 struct fw_state *fw_st = &fw_priv->fw_st;
163 static inline int fw_state_wait(struct fw_priv *fw_priv)
165 return __fw_state_wait_common(fw_priv, MAX_SCHEDULE_TIMEOUT);
168 static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv);
170 static struct fw_priv *__allocate_fw_priv(const char *fw_name,
177 struct fw_priv *fw_priv;
187 fw_priv = kzalloc(sizeof(*fw_priv), GFP_ATOMIC);
188 if (!fw_priv)
191 fw_priv->fw_name = kstrdup_const(fw_name, GFP_ATOMIC);
192 if (!fw_priv->fw_name) {
193 kfree(fw_priv);
197 kref_init(&fw_priv->ref);
198 fw_priv->fwc = fwc;
199 fw_priv->data = dbuf;
200 fw_priv->allocated_size = size;
201 fw_priv->offset = offset;
202 fw_priv->opt_flags = opt_flags;
203 fw_state_init(fw_priv);
205 INIT_LIST_HEAD(&fw_priv->pending_list);
208 pr_debug("%s: fw-%s fw_priv=%p\n", __func__, fw_name, fw_priv);
210 return fw_priv;
213 static struct fw_priv *__lookup_fw_priv(const char *fw_name)
215 struct fw_priv *tmp;
227 struct fw_priv **fw_priv,
233 struct fw_priv *tmp;
245 *fw_priv = tmp;
246 pr_debug("batched request - sharing the same struct fw_priv and lookup for multiple requests\n");
259 *fw_priv = tmp;
267 struct fw_priv *fw_priv = to_fw_priv(ref);
268 struct firmware_cache *fwc = fw_priv->fwc;
270 pr_debug("%s: fw-%s fw_priv=%p data=%p size=%u\n",
271 __func__, fw_priv->fw_name, fw_priv, fw_priv->data,
272 (unsigned int)fw_priv->size);
274 list_del(&fw_priv->list);
277 if (fw_is_paged_buf(fw_priv))
278 fw_free_paged_buf(fw_priv);
279 else if (!fw_priv->allocated_size)
280 vfree(fw_priv->data);
282 kfree_const(fw_priv->fw_name);
283 kfree(fw_priv);
286 static void free_fw_priv(struct fw_priv *fw_priv)
288 struct firmware_cache *fwc = fw_priv->fwc;
290 if (!kref_put(&fw_priv->ref, __free_fw_priv))
295 bool fw_is_paged_buf(struct fw_priv *fw_priv)
297 return fw_priv->is_paged_buf;
300 void fw_free_paged_buf(struct fw_priv *fw_priv)
304 if (!fw_priv->pages)
307 vunmap(fw_priv->data);
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;
317 int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed)
320 if (fw_priv->page_array_size < pages_needed) {
322 fw_priv->page_array_size * 2);
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;
338 while (fw_priv->nr_pages < pages_needed) {
339 fw_priv->pages[fw_priv->nr_pages] =
342 if (!fw_priv->pages[fw_priv->nr_pages])
344 fw_priv->nr_pages++;
350 int fw_map_paged_buf(struct fw_priv *fw_priv)
353 if (!fw_priv->pages)
356 vunmap(fw_priv->data);
357 fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0,
359 if (!fw_priv->data)
381 static int fw_decompress_xz_single(struct device *dev, struct fw_priv *fw_priv,
395 xz_buf.out_size = fw_priv->allocated_size;
396 xz_buf.out = fw_priv->data;
402 fw_priv->size = xz_buf.out_pos;
407 static int fw_decompress_xz_pages(struct device *dev, struct fw_priv *fw_priv,
424 fw_priv->is_paged_buf = true;
425 fw_priv->size = 0;
427 if (fw_grow_paged_buf(fw_priv, fw_priv->nr_pages + 1)) {
433 page = fw_priv->pages[fw_priv->nr_pages - 1];
439 fw_priv->size += xz_buf.out_pos;
447 err = fw_map_paged_buf(fw_priv);
454 static int fw_decompress_xz(struct device *dev, struct fw_priv *fw_priv,
458 if (fw_priv->data)
459 return fw_decompress_xz_single(dev, fw_priv, in_size, in_buffer);
461 return fw_decompress_xz_pages(dev, fw_priv, in_size, in_buffer);
484 fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
487 struct fw_priv *fw_priv,
499 if (!decompress && fw_priv->data) {
500 buffer = fw_priv->data;
501 msize = fw_priv->allocated_size;
517 fw_path[i], fw_priv->fw_name, suffix);
523 fw_priv->size = 0;
530 if ((fw_priv->opt_flags & FW_OPT_PARTIAL) && buffer)
534 rc = kernel_read_file_from_path_initns(path, fw_priv->offset,
553 fw_priv->fw_name);
554 rc = decompress(device, fw_priv, size, buffer);
559 fw_free_paged_buf(fw_priv);
564 fw_priv->fw_name);
565 if (!fw_priv->data)
566 fw_priv->data = buffer;
567 fw_priv->size = size;
569 fw_state_done(fw_priv);
589 static void fw_set_page_data(struct fw_priv *fw_priv, struct firmware *fw)
591 fw->priv = fw_priv;
592 fw->size = fw_priv->size;
593 fw->data = fw_priv->data;
595 pr_debug("%s: fw-%s fw_priv=%p data=%p size=%u\n",
596 __func__, fw_priv->fw_name, fw_priv, fw_priv->data,
597 (unsigned int)fw_priv->size);
678 struct fw_priv *fw_priv = fw->priv;
682 if (!fw_priv->size || fw_state_is_aborted(fw_priv)) {
695 if (device && (fw_priv->opt_flags & FW_OPT_UEVENT) &&
696 !(fw_priv->opt_flags & FW_OPT_NOCACHE)) {
697 ret = fw_add_devm_name(device, fw_priv->fw_name);
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);
713 fw_set_page_data(fw_priv, fw);
728 struct fw_priv *fw_priv;
743 ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size,
750 firmware->priv = fw_priv;
753 ret = fw_state_wait(fw_priv);
755 fw_set_page_data(fw_priv, firmware);
771 * the struct fw_priv and won't release it until all requests are woken
776 struct fw_priv *fw_priv;
782 fw_priv = fw->priv;
784 if (!fw_state_is_aborted(fw_priv))
785 fw_state_aborted(fw_priv);
1204 static struct fw_priv *lookup_fw_priv(const char *fw_name)
1206 struct fw_priv *tmp;
1229 struct fw_priv *fw_priv;
1237 fw_priv = lookup_fw_priv(fw_name);
1238 if (fw_priv) {
1239 free_fw_priv(fw_priv);
1276 static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv)
1278 const char *name = fw_priv->fw_name;
1279 struct firmware_cache *fwc = fw_priv->fwc;
1289 kref_get(&fw_priv->ref);
1524 static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv)