Subversion Repositories Kolibri OS

Rev

Rev 6082 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6082 Rev 6293
Line 347... Line 347...
347
 
347
 
348
	return ret;
348
	return ret;
349
}
349
}
Line -... Line 350...
-
 
350
EXPORT_SYMBOL(sg_alloc_table);
-
 
351
 
-
 
352
/**
-
 
353
 * sg_alloc_table_from_pages - Allocate and initialize an sg table from
-
 
354
 *			       an array of pages
-
 
355
 * @sgt:	The sg table header to use
-
 
356
 * @pages:	Pointer to an array of page pointers
-
 
357
 * @n_pages:	Number of pages in the pages array
-
 
358
 * @offset:     Offset from start of the first page to the start of a buffer
-
 
359
 * @size:       Number of valid bytes in the buffer (after offset)
-
 
360
 * @gfp_mask:	GFP allocation mask
-
 
361
 *
-
 
362
 *  Description:
-
 
363
 *    Allocate and initialize an sg table from a list of pages. Contiguous
-
 
364
 *    ranges of the pages are squashed into a single scatterlist node. A user
-
 
365
 *    may provide an offset at a start and a size of valid data in a buffer
-
 
366
 *    specified by the page array. The returned sg table is released by
-
 
367
 *    sg_free_table.
-
 
368
 *
-
 
369
 * Returns:
-
 
370
 *   0 on success, negative error on failure
-
 
371
 */
-
 
372
int sg_alloc_table_from_pages(struct sg_table *sgt,
-
 
373
	struct page **pages, unsigned int n_pages,
-
 
374
	unsigned long offset, unsigned long size,
-
 
375
	gfp_t gfp_mask)
-
 
376
{
-
 
377
	unsigned int chunks;
-
 
378
	unsigned int i;
-
 
379
	unsigned int cur_page;
-
 
380
	int ret;
-
 
381
	struct scatterlist *s;
-
 
382
 
-
 
383
	/* compute number of contiguous chunks */
-
 
384
	chunks = 1;
-
 
385
	for (i = 1; i < n_pages; ++i)
-
 
386
		if (page_to_pfn(pages[i]) != page_to_pfn(pages[i - 1]) + 1)
-
 
387
			++chunks;
-
 
388
 
-
 
389
	ret = sg_alloc_table(sgt, chunks, gfp_mask);
Line -... Line 390...
-
 
390
	if (unlikely(ret))
-
 
391
		return ret;
-
 
392
 
-
 
393
	/* merging chunks and putting them into the scatterlist */
-
 
394
	cur_page = 0;
Line -... Line 395...
-
 
395
	for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
-
 
396
		unsigned long chunk_size;
-
 
397
		unsigned int j;
-
 
398
 
-
 
399
		/* look for the end of the current chunk */
-
 
400
		for (j = cur_page + 1; j < n_pages; ++j)
-
 
401
			if (page_to_pfn(pages[j]) !=
-
 
402
			    page_to_pfn(pages[j - 1]) + 1)
-
 
403
				break;
-
 
404
 
-
 
405
		chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset;
-
 
406
		sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
-
 
407
		size -= chunk_size;
-
 
408
		offset = 0;
-
 
409
		cur_page = j;
-
 
410
	}
Line 350... Line 411...
350
EXPORT_SYMBOL(sg_alloc_table);
411
 
351
 
412
	return 0;
352
 
413
}
353
 
414
EXPORT_SYMBOL(sg_alloc_table_from_pages);