From 5342e7093ff298d9cbd40f9342b607adb02b2dd0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Jun 2019 14:26:24 +0200 Subject: firmware: Factor out the paged buffer handling code This is merely a preparation for the upcoming compressed firmware support and no functional changes. It moves the code to handle the paged buffer allocation and mapping out of fallback.c into the main code, so that they can be used commonly. Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/fallback.c | 61 ++++----------------------------- 1 file changed, 7 insertions(+), 54 deletions(-) (limited to 'drivers/base/firmware_loader/fallback.c') diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index 29becea1910d..62ee90b4db56 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -219,25 +219,6 @@ static ssize_t firmware_loading_show(struct device *dev, return sprintf(buf, "%d\n", loading); } -/* one pages buffer should be mapped/unmapped only once */ -static int map_fw_priv_pages(struct fw_priv *fw_priv) -{ - if (!fw_priv->pages) - return 0; - - vunmap(fw_priv->data); - fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0, - PAGE_KERNEL_RO); - if (!fw_priv->data) - return -ENOMEM; - - /* page table is no longer needed after mapping, let's free */ - kvfree(fw_priv->pages); - fw_priv->pages = NULL; - - return 0; -} - /** * firmware_loading_store() - set value in the 'loading' control file * @dev: device pointer @@ -283,7 +264,7 @@ static ssize_t firmware_loading_store(struct device *dev, * see the mapped 'buf->data' once the loading * is completed. * */ - rc = map_fw_priv_pages(fw_priv); + rc = fw_map_paged_buf(fw_priv); if (rc) dev_err(dev, "%s: map pages failed\n", __func__); @@ -388,41 +369,13 @@ out: static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size) { - struct fw_priv *fw_priv= fw_sysfs->fw_priv; - int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT; - - /* If the array of pages is too small, grow it... */ - if (fw_priv->page_array_size < pages_needed) { - int new_array_size = max(pages_needed, - fw_priv->page_array_size * 2); - struct page **new_pages; + int err; - new_pages = kvmalloc_array(new_array_size, sizeof(void *), - GFP_KERNEL); - if (!new_pages) { - fw_load_abort(fw_sysfs); - return -ENOMEM; - } - memcpy(new_pages, fw_priv->pages, - fw_priv->page_array_size * sizeof(void *)); - memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * - (new_array_size - fw_priv->page_array_size)); - kvfree(fw_priv->pages); - fw_priv->pages = new_pages; - fw_priv->page_array_size = new_array_size; - } - - while (fw_priv->nr_pages < pages_needed) { - fw_priv->pages[fw_priv->nr_pages] = - alloc_page(GFP_KERNEL | __GFP_HIGHMEM); - - if (!fw_priv->pages[fw_priv->nr_pages]) { - fw_load_abort(fw_sysfs); - return -ENOMEM; - } - fw_priv->nr_pages++; - } - return 0; + err = fw_grow_paged_buf(fw_sysfs->fw_priv, + PAGE_ALIGN(min_size) >> PAGE_SHIFT); + if (err) + fw_load_abort(fw_sysfs); + return err; } /** -- cgit v1.2.3