// SPDX-License-Identifier: GPL-2.0 /* * 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. * * Released under the GPLv2 only.
*/
/* 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_DMA_MINALIGN.
*/ if (ARCH_DMA_MINALIGN <= 32)
; /* Original value is okay */ elseif (ARCH_DMA_MINALIGN <= 64)
pool_max[0] = 64; elseif (ARCH_DMA_MINALIGN <= 128)
pool_max[0] = 0; /* Don't use this pool */ else
BUILD_BUG(); /* We don't allow this */
}
/* SETUP primitives */
/** * hcd_buffer_create - initialize buffer pools * @hcd: the bus whose buffer pools are to be initialized * * Context: task context, might sleep * * 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 (hcd->localmem_pool || !hcd_uses_dma(hcd)) 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.sysdev,
size, size, 0); if (!hcd->pool[i]) {
hcd_buffer_destroy(hcd); return -ENOMEM;
}
} return 0;
}
/** * hcd_buffer_destroy - deallocate buffer pools * @hcd: the bus whose buffer pools are to be destroyed * * Context: task context, might sleep * * 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++) {
dma_pool_destroy(hcd->pool[i]);
hcd->pool[i] = NULL;
}
}
/* sometimes alloc/free could use kmalloc with GFP_DMA, for * better sharing and to leverage mm/slab.c intelligence.
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.