X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fcore%2Fmemory.c;h=93537ab7c2acb4c2e0864076ddd250d955ef6252;hb=refs%2Fheads%2Fvserver;hp=1f8c8d93409d35c72217a63e1cbf9166d9e9ff19;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/sound/core/memory.c b/sound/core/memory.c index 1f8c8d934..93537ab7c 100644 --- a/sound/core/memory.c +++ b/sound/core/memory.c @@ -1,7 +1,7 @@ /* * Copyright (c) by Jaroslav Kysela * - * Memory allocation helpers. + * Misc memory accessors * * * This program is free software; you can redistribute it and/or modify @@ -20,282 +20,9 @@ * */ -#include +#include #include #include -#include -#include -#include -#include -#include -#include - -/* - * memory allocation helpers and debug routines - */ - -#ifdef CONFIG_SND_DEBUG_MEMORY - -struct snd_alloc_track { - unsigned long magic; - void *caller; - size_t size; - struct list_head list; - long data[0]; -}; - -#define snd_alloc_track_entry(obj) (struct snd_alloc_track *)((char*)obj - (unsigned long)((struct snd_alloc_track *)0)->data) - -static long snd_alloc_kmalloc; -static long snd_alloc_vmalloc; -static LIST_HEAD(snd_alloc_kmalloc_list); -static LIST_HEAD(snd_alloc_vmalloc_list); -static spinlock_t snd_alloc_kmalloc_lock = SPIN_LOCK_UNLOCKED; -static spinlock_t snd_alloc_vmalloc_lock = SPIN_LOCK_UNLOCKED; -#define KMALLOC_MAGIC 0x87654321 -#define VMALLOC_MAGIC 0x87654320 -static snd_info_entry_t *snd_memory_info_entry; - -void snd_memory_init(void) -{ - snd_alloc_kmalloc = 0; - snd_alloc_vmalloc = 0; -} - -void snd_memory_done(void) -{ - struct list_head *head; - struct snd_alloc_track *t; - - if (snd_alloc_kmalloc > 0) - snd_printk(KERN_ERR "Not freed snd_alloc_kmalloc = %li\n", snd_alloc_kmalloc); - if (snd_alloc_vmalloc > 0) - snd_printk(KERN_ERR "Not freed snd_alloc_vmalloc = %li\n", snd_alloc_vmalloc); - for (head = snd_alloc_kmalloc_list.prev; - head != &snd_alloc_kmalloc_list; head = head->prev) { - t = list_entry(head, struct snd_alloc_track, list); - if (t->magic != KMALLOC_MAGIC) { - snd_printk(KERN_ERR "Corrupted kmalloc\n"); - break; - } - snd_printk(KERN_ERR "kmalloc(%ld) from %p not freed\n", (long) t->size, t->caller); - } - for (head = snd_alloc_vmalloc_list.prev; - head != &snd_alloc_vmalloc_list; head = head->prev) { - t = list_entry(head, struct snd_alloc_track, list); - if (t->magic != VMALLOC_MAGIC) { - snd_printk(KERN_ERR "Corrupted vmalloc\n"); - break; - } - snd_printk(KERN_ERR "vmalloc(%ld) from %p not freed\n", (long) t->size, t->caller); - } -} - -void *__snd_kmalloc(size_t size, int flags, void *caller) -{ - unsigned long cpu_flags; - struct snd_alloc_track *t; - void *ptr; - - ptr = snd_wrapper_kmalloc(size + sizeof(struct snd_alloc_track), flags); - if (ptr != NULL) { - t = (struct snd_alloc_track *)ptr; - t->magic = KMALLOC_MAGIC; - t->caller = caller; - spin_lock_irqsave(&snd_alloc_kmalloc_lock, cpu_flags); - list_add_tail(&t->list, &snd_alloc_kmalloc_list); - spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, cpu_flags); - t->size = size; - snd_alloc_kmalloc += size; - ptr = t->data; - } - return ptr; -} - -#define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0)); -void *snd_hidden_kmalloc(size_t size, int flags) -{ - return _snd_kmalloc(size, flags); -} - -void snd_hidden_kfree(const void *obj) -{ - unsigned long flags; - struct snd_alloc_track *t; - if (obj == NULL) { - snd_printk(KERN_WARNING "null kfree (called from %p)\n", __builtin_return_address(0)); - return; - } - t = snd_alloc_track_entry(obj); - if (t->magic != KMALLOC_MAGIC) { - snd_printk(KERN_WARNING "bad kfree (called from %p)\n", __builtin_return_address(0)); - return; - } - spin_lock_irqsave(&snd_alloc_kmalloc_lock, flags); - list_del(&t->list); - spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, flags); - t->magic = 0; - snd_alloc_kmalloc -= t->size; - obj = t; - snd_wrapper_kfree(obj); -} - -void *_snd_magic_kcalloc(unsigned long magic, size_t size, int flags) -{ - unsigned long *ptr; - ptr = _snd_kmalloc(size + sizeof(unsigned long), flags); - if (ptr) { - *ptr++ = magic; - memset(ptr, 0, size); - } - return ptr; -} - -void *_snd_magic_kmalloc(unsigned long magic, size_t size, int flags) -{ - unsigned long *ptr; - ptr = _snd_kmalloc(size + sizeof(unsigned long), flags); - if (ptr) - *ptr++ = magic; - return ptr; -} - -void snd_magic_kfree(void *_ptr) -{ - unsigned long *ptr = _ptr; - if (ptr == NULL) { - snd_printk(KERN_WARNING "null snd_magic_kfree (called from %p)\n", __builtin_return_address(0)); - return; - } - *--ptr = 0; - { - struct snd_alloc_track *t; - t = snd_alloc_track_entry(ptr); - if (t->magic != KMALLOC_MAGIC) { - snd_printk(KERN_ERR "bad snd_magic_kfree (called from %p)\n", __builtin_return_address(0)); - return; - } - } - snd_hidden_kfree(ptr); - return; -} - -void *snd_hidden_vmalloc(unsigned long size) -{ - void *ptr; - ptr = snd_wrapper_vmalloc(size + sizeof(struct snd_alloc_track)); - if (ptr) { - struct snd_alloc_track *t = (struct snd_alloc_track *)ptr; - t->magic = VMALLOC_MAGIC; - t->caller = __builtin_return_address(0); - spin_lock(&snd_alloc_vmalloc_lock); - list_add_tail(&t->list, &snd_alloc_vmalloc_list); - spin_unlock(&snd_alloc_vmalloc_lock); - t->size = size; - snd_alloc_vmalloc += size; - ptr = t->data; - } - return ptr; -} - -void snd_hidden_vfree(void *obj) -{ - struct snd_alloc_track *t; - if (obj == NULL) { - snd_printk(KERN_WARNING "null vfree (called from %p)\n", __builtin_return_address(0)); - return; - } - t = snd_alloc_track_entry(obj); - if (t->magic != VMALLOC_MAGIC) { - snd_printk(KERN_ERR "bad vfree (called from %p)\n", __builtin_return_address(0)); - return; - } - spin_lock(&snd_alloc_vmalloc_lock); - list_del(&t->list); - spin_unlock(&snd_alloc_vmalloc_lock); - t->magic = 0; - snd_alloc_vmalloc -= t->size; - obj = t; - snd_wrapper_vfree(obj); -} - -static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) -{ - snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc); - snd_iprintf(buffer, "vmalloc: %li bytes\n", snd_alloc_vmalloc); -} - -int __init snd_memory_info_init(void) -{ - snd_info_entry_t *entry; - - entry = snd_info_create_module_entry(THIS_MODULE, "meminfo", NULL); - if (entry) { - entry->c.text.read_size = 256; - entry->c.text.read = snd_memory_info_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - snd_memory_info_entry = entry; - return 0; -} - -int __exit snd_memory_info_done(void) -{ - if (snd_memory_info_entry) - snd_info_unregister(snd_memory_info_entry); - return 0; -} - -#else - -#define _snd_kmalloc kmalloc - -#endif /* CONFIG_SND_DEBUG_MEMORY */ - -/** - * snd_kcalloc - memory allocation and zero-clear - * @size: the size to allocate in bytes - * @flags: allocation conditions, GFP_XXX - * - * Allocates a memory chunk via kmalloc() and initializes it to zero. - * - * Returns the pointer, or NULL if no enoguh memory. - */ -void *snd_kcalloc(size_t size, int flags) -{ - void *ptr; - - ptr = _snd_kmalloc(size, flags); - if (ptr) - memset(ptr, 0, size); - return ptr; -} - -/** - * snd_kmalloc_strdup - copy the string - * @string: the original string - * @flags: allocation conditions, GFP_XXX - * - * Allocates a memory chunk via kmalloc() and copies the string to it. - * - * Returns the pointer, or NULL if no enoguh memory. - */ -char *snd_kmalloc_strdup(const char *string, int flags) -{ - size_t len; - char *ptr; - - if (!string) - return NULL; - len = strlen(string) + 1; - ptr = _snd_kmalloc(len, flags); - if (ptr) - memcpy(ptr, string, len); - return ptr; -} /** * copy_to_user_fromio - copy data from mmio-space to user-space @@ -307,17 +34,17 @@ char *snd_kmalloc_strdup(const char *string, int flags) * * Returns zero if successful, or non-zero on failure. */ -int copy_to_user_fromio(void *dst, unsigned long src, size_t count) +int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count) { #if defined(__i386__) || defined(CONFIG_SPARC32) - return copy_to_user(dst, (const void*)src, count) ? -EFAULT : 0; + return copy_to_user(dst, (const void __force*)src, count) ? -EFAULT : 0; #else char buf[256]; while (count) { size_t c = count; if (c > sizeof(buf)) c = sizeof(buf); - memcpy_fromio(buf, (void*)src, c); + memcpy_fromio(buf, (void __iomem *)src, c); if (copy_to_user(dst, buf, c)) return -EFAULT; count -= c; @@ -328,6 +55,8 @@ int copy_to_user_fromio(void *dst, unsigned long src, size_t count) #endif } +EXPORT_SYMBOL(copy_to_user_fromio); + /** * copy_from_user_toio - copy data from user-space to mmio-space * @dst: the destination pointer on mmio-space @@ -338,10 +67,10 @@ int copy_to_user_fromio(void *dst, unsigned long src, size_t count) * * Returns zero if successful, or non-zero on failure. */ -int copy_from_user_toio(unsigned long dst, const void *src, size_t count) +int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count) { #if defined(__i386__) || defined(CONFIG_SPARC32) - return copy_from_user((void*)dst, src, count) ? -EFAULT : 0; + return copy_from_user((void __force *)dst, src, count) ? -EFAULT : 0; #else char buf[256]; while (count) { @@ -350,7 +79,7 @@ int copy_from_user_toio(unsigned long dst, const void *src, size_t count) c = sizeof(buf); if (copy_from_user(buf, src, c)) return -EFAULT; - memcpy_toio((void*)dst, buf, c); + memcpy_toio(dst, buf, c); count -= c; dst += c; src += c; @@ -358,3 +87,5 @@ int copy_from_user_toio(unsigned long dst, const void *src, size_t count) return 0; #endif } + +EXPORT_SYMBOL(copy_from_user_toio);