resources/KernelSource_4_19v/drivers/fpga/fpga-mgr.c
/**
 * fpga_mgr_buf_load - load fpga from image in buffer
 * @mgr:	fpga manager
 * @info:	fpga image info
 * @buf:	buffer contain fpga image
 * @count:	byte count of buf
 *
 * Step the low level fpga manager through the device-specific steps of getting
 * an FPGA ready to be configured, writing the image to it, then doing whatever
 * post-configuration steps necessary.  This code assumes the caller got the
 * mgr pointer from of_fpga_mgr_get() and checked that it is not an error code.
 *
 * Return: 0 on success, negative error code otherwise.
 */
load fpga from image in buffer
@mgr:        fpga manager
@info:       fpga image info
@buf:        buffer contain fpga image
@count:      byte count of buf

Step the low level fpga manager through the device-specific steps of getting
an FPGA ready to be configured, writing the image to it, then doing whatever
post-configuration steps necessary.  This code assumes the caller got the
mgr pointer from of_fpga_mgr_get() and checked that it is not an error code.

0 on success, negative error code otherwise.
load fpga from image in buffer @mgr : fpga manager @info : fpga image info @buf : buffer contain fpga image @count : byte count of buf Step the low level fpga manager through the device - specific steps of getting an FPGA ready to be configured writing the image to it then doing whatever post - configuration steps necessary . This code assumes the caller got the mgr pointer from of_fpga_mgr_get () and checked that it is not an error code . 0 on success negative error code otherwise .
static int fpga_mgr_buf_load(struct fpga_manager *mgr,
			     struct fpga_image_info *info,
			     const char *buf, size_t count)
{
	struct page **pages;
	struct sg_table sgt;
	const void *p;
	int nr_pages;
	int index;
	int rc;
	if (mgr->mops->write)
		return fpga_mgr_buf_load_mapped(mgr, info, buf, count);
	nr_pages = DIV_ROUND_UP((unsigned long)buf + count, PAGE_SIZE) -
		   (unsigned long)buf / PAGE_SIZE;
	pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL);
	if (!pages)
		return -ENOMEM;
	p = buf - offset_in_page(buf);
	for (index = 0; index < nr_pages; index++) {
		if (is_vmalloc_addr(p))
			pages[index] = vmalloc_to_page(p);
		else
			pages[index] = kmap_to_page((void *)p);
		if (!pages[index]) {
			kfree(pages);
			return -EFAULT;
		}
		p += PAGE_SIZE;
	}
	rc = sg_alloc_table_from_pages(&sgt, pages, index, offset_in_page(buf),
				       count, GFP_KERNEL);
	kfree(pages);
	if (rc)
		return rc;
	rc = fpga_mgr_buf_load_sg(mgr, info, &sgt);
	sg_free_table(&sgt);
	return rc;
}
static int fpga_mgr_buf_load ( struct fpga_manager * mgr , struct fpga_image_info * info , const char * buf , size_t count ) { struct page * * pages ; struct sg_table sgt ; const void * p ; int nr_pages ; int index ; int rc ; if ( mgr -> mops -> write ) return fpga_mgr_buf_load_mapped ( mgr , info , buf , count ) ; nr_pages = DIV_ROUND_UP ( ( unsigned long ) buf + count , PAGE_SIZE ) - ( unsigned long ) buf / PAGE_SIZE ; pages = kmalloc_array ( nr_pages , sizeof ( struct page * ) , GFP_KERNEL ) ; if ( ! pages ) return - ENOMEM ; p = buf - offset_in_page ( buf ) ; for ( index = 0 ; index < nr_pages ; index ++ ) { if ( is_vmalloc_addr ( p ) ) pages [ index ] = vmalloc_to_page ( p ) ; else pages [ index ] = kmap_to_page ( ( void * ) p ) ; if ( ! pages [ index ] ) { kfree ( pages ) ; return - EFAULT ; } p += PAGE_SIZE ; } rc = sg_alloc_table_from_pages ( & sgt , pages , index , offset_in_page ( buf ) , count , GFP_KERNEL ) ; kfree ( pages ) ; if ( rc ) return rc ; rc = fpga_mgr_buf_load_sg ( mgr , info , & sgt ) ; sg_free_table ( & sgt ) ; return rc ; }
fpga_mgr_buf_load - load fpga from image in buffer
 @mgr:        fpga manager
 @info:       fpga image info
 @buf:        buffer contain fpga image
 @count:      byte count of buf
fpga_mgr_buf_load - load fpga from image in buffer @mgr : fpga manager @info : fpga image info @buf : buffer contain fpga image @count : byte count of buf
/*
	 * This is just a fast path if the caller has already created a
	 * contiguous kernel buffer and the driver doesn't require SG, non-SG
	 * drivers will still work on the slow path.
	 */ /*
	 * Convert the linear kernel pointer into a sg_table of pages for use
	 * by the driver.
	 */ /*
	 * The temporary pages list is used to code share the merging algorithm
	 * in sg_alloc_table_from_pages
	 */