cregit-Linux how code gets into the kernel

Release 4.7 drivers/usb/core/buffer.c

Directory: drivers/usb/core
/*
 * DMA memory management for framework level HCD code (hc_driver)
 *
 * This implementation plugs in through generic "usb_bus" level methods,
 * and should work with all USB controllers, regardless of bus type.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>


/*
 * DMA-Coherent Buffers
 */

/* FIXME tune these based on pool statistics ... */

static size_t pool_max[HCD_BUFFER_POOLS] = {
	32, 128, 512, 2048,
};


void __init usb_init_pool_max(void) { /* * The pool_max values must never be smaller than * ARCH_KMALLOC_MINALIGN. */ if (ARCH_KMALLOC_MINALIGN <= 32) ; /* Original value is okay */ else if (ARCH_KMALLOC_MINALIGN <= 64) pool_max[0] = 64; else if (ARCH_KMALLOC_MINALIGN <= 128) pool_max[0] = 0; /* Don't use this pool */ else BUILD_BUG(); /* We don't allow this */ }

Contributors

PersonTokensPropCommitsCommitProp
sebastian andrzej siewiorsebastian andrzej siewior51100.00%1100.00%
Total51100.00%1100.00%

/* SETUP primitives */ /** * hcd_buffer_create - initialize buffer pools * @hcd: the bus whose buffer pools are to be initialized * Context: !in_interrupt() * * Call this as part of initializing a host controller that uses the dma * memory allocators. It initializes some pools of dma-coherent memory that * will be shared by all drivers using that controller. * * Call hcd_buffer_destroy() to clean up after using those pools. * * Return: 0 if successful. A negative errno value otherwise. */
int hcd_buffer_create(struct usb_hcd *hcd) { char name[16]; int i, size; if (!IS_ENABLED(CONFIG_HAS_DMA) || (!hcd->self.controller->dma_mask && !(hcd->driver->flags & HCD_LOCAL_MEM))) return 0; for (i = 0; i < HCD_BUFFER_POOLS; i++) { size = pool_max[i]; if (!size) continue; snprintf(name, sizeof(name), "buffer-%d", size); hcd->pool[i] = dma_pool_create(name, hcd->self.controller, size, size, 0); if (!hcd->pool[i]) { hcd_buffer_destroy(hcd); return -ENOMEM; } } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
david brownelldavid brownell10069.44%114.29%
chris humbertchris humbert149.72%114.29%
magnus dammmagnus damm117.64%114.29%
geert uytterhoevengeert uytterhoeven85.56%114.29%
greg kroah-hartmangreg kroah-hartman53.47%114.29%
deepak saxenadeepak saxena42.78%114.29%
nizam haidernizam haider21.39%114.29%
Total144100.00%7100.00%

/** * hcd_buffer_destroy - deallocate buffer pools * @hcd: the bus whose buffer pools are to be destroyed * Context: !in_interrupt() * * This frees the buffer pools created by hcd_buffer_create(). */
void hcd_buffer_destroy(struct usb_hcd *hcd) { int i; if (!IS_ENABLED(CONFIG_HAS_DMA)) return; for (i = 0; i < HCD_BUFFER_POOLS; i++) { struct dma_pool *pool = hcd->pool[i]; if (pool) { dma_pool_destroy(pool); hcd->pool[i] = NULL; } } }

Contributors

PersonTokensPropCommitsCommitProp
david brownelldavid brownell5782.61%125.00%
geert uytterhoevengeert uytterhoeven913.04%125.00%
deepak saxenadeepak saxena22.90%125.00%
mika kukkonenmika kukkonen11.45%125.00%
Total69100.00%4100.00%

/* sometimes alloc/free could use kmalloc with GFP_DMA, for * better sharing and to leverage mm/slab.c intelligence. */
void *hcd_buffer_alloc( struct usb_bus *bus, size_t size, gfp_t mem_flags, dma_addr_t *dma ) { struct usb_hcd *hcd = bus_to_hcd(bus); int i; if (size == 0) return NULL; /* some USB hosts just use PIO */ if (!IS_ENABLED(CONFIG_HAS_DMA) || (!bus->controller->dma_mask && !(hcd->driver->flags & HCD_LOCAL_MEM))) { *dma = ~(dma_addr_t) 0; return kmalloc(size, mem_flags); } for (i = 0; i < HCD_BUFFER_POOLS; i++) { if (size <= pool_max[i]) return dma_pool_alloc(hcd->pool[i], mem_flags, dma); } return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags); }

Contributors

PersonTokensPropCommitsCommitProp
david brownelldavid brownell10773.29%222.22%
magnus dammmagnus damm117.53%111.11%
chunfeng yunchunfeng yun96.16%111.11%
geert uytterhoevengeert uytterhoeven85.48%111.11%
deepak saxenadeepak saxena64.11%111.11%
alan sternalan stern32.05%111.11%
al viroal viro10.68%111.11%
johannes bergjohannes berg10.68%111.11%
Total146100.00%9100.00%


void hcd_buffer_free( struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma ) { struct usb_hcd *hcd = bus_to_hcd(bus); int i; if (!addr) return; if (!IS_ENABLED(CONFIG_HAS_DMA) || (!bus->controller->dma_mask && !(hcd->driver->flags & HCD_LOCAL_MEM))) { kfree(addr); return; } for (i = 0; i < HCD_BUFFER_POOLS; i++) { if (size <= pool_max[i]) { dma_pool_free(hcd->pool[i], addr, dma); return; } } dma_free_coherent(hcd->self.controller, size, addr, dma); }

Contributors

PersonTokensPropCommitsCommitProp
david brownelldavid brownell10479.39%342.86%
magnus dammmagnus damm118.40%114.29%
geert uytterhoevengeert uytterhoeven86.11%114.29%
deepak saxenadeepak saxena53.82%114.29%
alan sternalan stern32.29%114.29%
Total131100.00%7100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
david brownelldavid brownell40367.73%522.73%
sebastian andrzej siewiorsebastian andrzej siewior538.91%14.55%
magnus dammmagnus damm335.55%14.55%
geert uytterhoevengeert uytterhoeven335.55%14.55%
deepak saxenadeepak saxena294.87%14.55%
chris humbertchris humbert142.35%14.55%
chunfeng yunchunfeng yun91.51%14.55%
alan sternalan stern61.01%14.55%
greg kroah-hartmangreg kroah-hartman50.84%14.55%
nizam haidernizam haider20.34%14.55%
tobias ollmanntobias ollmann10.17%14.55%
yacine belkadiyacine belkadi10.17%14.55%
johannes bergjohannes berg10.17%14.55%
al viroal viro10.17%14.55%
christoph lameterchristoph lameter10.17%14.55%
mika kukkonenmika kukkonen10.17%14.55%
rahul bedarkarrahul bedarkar10.17%14.55%
eric lescoueteric lescouet10.17%14.55%
Total595100.00%22100.00%
Directory: drivers/usb/core
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}