diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 9 | ||||
-rw-r--r-- | lib/Kconfig.debug | 41 | ||||
-rw-r--r-- | lib/Makefile | 11 | ||||
-rw-r--r-- | lib/bitmap.c | 24 | ||||
-rw-r--r-- | lib/bust_spinlocks.c | 12 | ||||
-rw-r--r-- | lib/cmdline.c | 8 | ||||
-rw-r--r-- | lib/cpumask.c | 18 | ||||
-rw-r--r-- | lib/devres.c | 326 | ||||
-rw-r--r-- | lib/div64.c | 22 | ||||
-rw-r--r-- | lib/fault-inject.c | 41 | ||||
-rw-r--r-- | lib/genalloc.c | 4 | ||||
-rw-r--r-- | lib/idr.c | 4 | ||||
-rw-r--r-- | lib/iomap.c | 3 | ||||
-rw-r--r-- | lib/kobject.c | 145 | ||||
-rw-r--r-- | lib/kobject_uevent.c | 28 | ||||
-rw-r--r-- | lib/kref.c | 2 | ||||
-rw-r--r-- | lib/sha1.c | 9 | ||||
-rw-r--r-- | lib/sort.c | 2 | ||||
-rw-r--r-- | lib/string.c | 36 | ||||
-rw-r--r-- | lib/swiotlb.c | 126 | ||||
-rw-r--r-- | lib/textsearch.c | 4 | ||||
-rw-r--r-- | lib/vsprintf.c | 15 |
22 files changed, 676 insertions, 214 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 9b03581..3842499 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -101,9 +101,14 @@ config TEXTSEARCH_FSM config PLIST boolean -config IOMAP_COPY +config HAS_IOMEM boolean - depends on !UML + depends on !NO_IOMEM + default y + +config HAS_IOPORT + boolean + depends on HAS_IOMEM && !NO_IOPORT default y endmenu diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 5c268187..79afd00 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -77,6 +77,15 @@ config DEBUG_KERNEL Say Y here if you are developing drivers or trying to debug and identify kernel problems. +config DEBUG_SHIRQ + bool "Debug shared IRQ handlers" + depends on DEBUG_KERNEL && GENERIC_HARDIRQS + help + Enable this to generate a spurious interrupt as soon as a shared + interrupt handler is registered, and just before one is deregistered. + Drivers ought to be able to handle interrupts coming in at those + points; some don't and need to be caught. + config LOG_BUF_SHIFT int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" if DEBUG_KERNEL range 12 21 @@ -125,6 +134,17 @@ config SCHEDSTATS application, you can say N to avoid the very slight overhead this adds. +config TIMER_STATS + bool "Collect kernel timers statistics" + depends on DEBUG_KERNEL && PROC_FS + help + If you say Y here, additional code will be inserted into the + timer routines to collect statistics about kernel timers being + reprogrammed. The statistics can be read from /proc/timer_stats. + The statistics collection is started by writing 1 to /proc/timer_stats, + writing 0 stops it. This feature is useful to collect information + about timer usage patterns in kernel and userspace. + config DEBUG_SLAB bool "Debug slab memory allocations" depends on DEBUG_KERNEL && SLAB @@ -181,19 +201,11 @@ config DEBUG_MUTEXES This feature allows mutex semantics violations to be detected and reported. -config DEBUG_RWSEMS - bool "RW-sem debugging: basic checks" - depends on DEBUG_KERNEL - help - This feature allows read-write semaphore semantics violations to - be detected and reported. - config DEBUG_LOCK_ALLOC bool "Lock debugging: detect incorrect freeing of live locks" depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT select DEBUG_SPINLOCK select DEBUG_MUTEXES - select DEBUG_RWSEMS select LOCKDEP help This feature will check whether any held lock (spinlock, rwlock, @@ -209,7 +221,6 @@ config PROVE_LOCKING select LOCKDEP select DEBUG_SPINLOCK select DEBUG_MUTEXES - select DEBUG_RWSEMS select DEBUG_LOCK_ALLOC default n help @@ -250,7 +261,7 @@ config LOCKDEP bool depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT select STACKTRACE - select FRAME_POINTER if !X86 + select FRAME_POINTER if !X86 && !MIPS select KALLSYMS select KALLSYMS_ALL @@ -400,8 +411,6 @@ config LKDTM config FAULT_INJECTION bool "Fault-injection framework" depends on DEBUG_KERNEL - depends on STACKTRACE - select FRAME_POINTER help Provide fault-injection framework. For more details, see Documentation/fault-injection/. @@ -429,3 +438,11 @@ config FAULT_INJECTION_DEBUG_FS depends on FAULT_INJECTION && SYSFS && DEBUG_FS help Enable configuration of fault-injection capabilities via debugfs. + +config FAULT_INJECTION_STACKTRACE_FILTER + bool "stacktrace filter for fault-injection capabilities" + depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT + select STACKTRACE + select FRAME_POINTER + help + Provide stacktrace filter for fault-injection capabilities diff --git a/lib/Makefile b/lib/Makefile index 77b4bad..ae57f35 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -3,8 +3,8 @@ # lib-y := ctype.o string.o vsprintf.o cmdline.o \ - bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ - idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \ + rbtree.o radix-tree.o dump_stack.o \ + idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \ sha1.o irq_regs.o reciprocal_div.o lib-$(CONFIG_MMU) += ioremap.o @@ -12,14 +12,16 @@ lib-$(CONFIG_SMP) += cpumask.o lib-y += kobject.o kref.o kobject_uevent.o klist.o -obj-y += sort.o parser.o halfmd4.o debug_locks.o random32.o +obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ + bust_spinlocks.o ifeq ($(CONFIG_DEBUG_KOBJECT),y) CFLAGS_kobject.o += -DDEBUG CFLAGS_kobject_uevent.o += -DDEBUG endif -obj-$(CONFIG_IOMAP_COPY) += iomap_copy.o +obj-$(CONFIG_GENERIC_IOMAP) += iomap.o +obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o @@ -41,7 +43,6 @@ obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o obj-$(CONFIG_CRC16) += crc16.o obj-$(CONFIG_CRC32) += crc32.o obj-$(CONFIG_LIBCRC32C) += libcrc32c.o -obj-$(CONFIG_GENERIC_IOMAP) += iomap.o obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ diff --git a/lib/bitmap.c b/lib/bitmap.c index 037fa9a..26ebafa 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -95,12 +95,12 @@ void __bitmap_complement(unsigned long *dst, const unsigned long *src, int bits) } EXPORT_SYMBOL(__bitmap_complement); -/* +/** * __bitmap_shift_right - logical right shift of the bits in a bitmap - * @dst - destination bitmap - * @src - source bitmap - * @nbits - shift by this many bits - * @bits - bitmap size, in bits + * @dst : destination bitmap + * @src : source bitmap + * @shift : shift by this many bits + * @bits : bitmap size, in bits * * Shifting right (dividing) means moving bits in the MS -> LS bit * direction. Zeros are fed into the vacated MS positions and the @@ -139,12 +139,12 @@ void __bitmap_shift_right(unsigned long *dst, EXPORT_SYMBOL(__bitmap_shift_right); -/* +/** * __bitmap_shift_left - logical left shift of the bits in a bitmap - * @dst - destination bitmap - * @src - source bitmap - * @nbits - shift by this many bits - * @bits - bitmap size, in bits + * @dst : destination bitmap + * @src : source bitmap + * @shift : shift by this many bits + * @bits : bitmap size, in bits * * Shifting left (multiplying) means moving bits in the LS -> MS * direction. Zeros are fed into the vacated LS bit positions @@ -529,7 +529,7 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits) } EXPORT_SYMBOL(bitmap_parselist); -/* +/** * bitmap_pos_to_ord(buf, pos, bits) * @buf: pointer to a bitmap * @pos: a bit position in @buf (0 <= @pos < @bits) @@ -804,7 +804,7 @@ EXPORT_SYMBOL(bitmap_find_free_region); * @pos: beginning of bit region to release * @order: region size (log base 2 of number of bits) to release * - * This is the complement to __bitmap_find_free_region and releases + * This is the complement to __bitmap_find_free_region() and releases * the found region (by clearing it in the bitmap). * * No return value. diff --git a/lib/bust_spinlocks.c b/lib/bust_spinlocks.c index a2055bc..accb356 100644 --- a/lib/bust_spinlocks.c +++ b/lib/bust_spinlocks.c @@ -14,24 +14,16 @@ #include <linux/vt_kern.h> -void bust_spinlocks(int yes) +void __attribute__((weak)) bust_spinlocks(int yes) { if (yes) { oops_in_progress = 1; } else { - int loglevel_save = console_loglevel; #ifdef CONFIG_VT unblank_screen(); #endif oops_in_progress = 0; - /* - * OK, the message is on the console. Now we call printk() - * without oops_in_progress set so that printk() will give klogd - * and the blanked console a poke. Hold onto your hats... - */ - console_loglevel = 15; /* NMI oopser may have shut the console up */ - printk(" "); - console_loglevel = loglevel_save; + wake_up_klogd(); } } diff --git a/lib/cmdline.c b/lib/cmdline.c index 8a5b530..f596c08d 100644 --- a/lib/cmdline.c +++ b/lib/cmdline.c @@ -43,10 +43,10 @@ static int get_range(char **str, int *pint) * comma as well. * * Return values: - * 0 : no int in string - * 1 : int found, no subsequent comma - * 2 : int found including a subsequent comma - * 3 : hyphen found to denote a range + * 0 - no int in string + * 1 - int found, no subsequent comma + * 2 - int found including a subsequent comma + * 3 - hyphen found to denote a range */ int get_option (char **str, int *pint) diff --git a/lib/cpumask.c b/lib/cpumask.c index 3a67dc5..1ea2c18 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c @@ -15,22 +15,8 @@ int __next_cpu(int n, const cpumask_t *srcp) } EXPORT_SYMBOL(__next_cpu); -/* - * Find the highest possible smp_processor_id() - * - * Note: if we're prepared to assume that cpu_possible_map never changes - * (reasonable) then this function should cache its return value. - */ -int highest_possible_processor_id(void) -{ - unsigned int cpu; - unsigned highest = 0; - - for_each_cpu_mask(cpu, cpu_possible_map) - highest = cpu; - return highest; -} -EXPORT_SYMBOL(highest_possible_processor_id); +int nr_cpu_ids; +EXPORT_SYMBOL(nr_cpu_ids); int __any_online_cpu(const cpumask_t *mask) { diff --git a/lib/devres.c b/lib/devres.c new file mode 100644 index 0000000..b1d336c --- /dev/null +++ b/lib/devres.c @@ -0,0 +1,326 @@ +#include <linux/pci.h> +#include <linux/io.h> +#include <linux/module.h> + +static void devm_ioremap_release(struct device *dev, void *res) +{ + iounmap(*(void __iomem **)res); +} + +static int devm_ioremap_match(struct device *dev, void *res, void *match_data) +{ + return *(void **)res == match_data; +} + +/** + * devm_ioremap - Managed ioremap() + * @dev: Generic device to remap IO address for + * @offset: BUS offset to map + * @size: Size of map + * + * Managed ioremap(). Map is automatically unmapped on driver detach. + */ +void __iomem *devm_ioremap(struct device *dev, unsigned long offset, + unsigned long size) +{ + void __iomem **ptr, *addr; + + ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + addr = ioremap(offset, size); + if (addr) { + *ptr = addr; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return addr; +} +EXPORT_SYMBOL(devm_ioremap); + +/** + * devm_ioremap_nocache - Managed ioremap_nocache() + * @dev: Generic device to remap IO address for + * @offset: BUS offset to map + * @size: Size of map + * + * Managed ioremap_nocache(). Map is automatically unmapped on driver + * detach. + */ +void __iomem *devm_ioremap_nocache(struct device *dev, unsigned long offset, + unsigned long size) +{ + void __iomem **ptr, *addr; + + ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + addr = ioremap_nocache(offset, size); + if (addr) { + *ptr = addr; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return addr; +} +EXPORT_SYMBOL(devm_ioremap_nocache); + +/** + * devm_iounmap - Managed iounmap() + * @dev: Generic device to unmap for + * @addr: Address to unmap + * + * Managed iounmap(). @addr must have been mapped using devm_ioremap*(). + */ +void devm_iounmap(struct device *dev, void __iomem *addr) +{ + iounmap(addr); + WARN_ON(devres_destroy(dev, devm_ioremap_release, devm_ioremap_match, + (void *)addr)); +} +EXPORT_SYMBOL(devm_iounmap); + +#ifdef CONFIG_HAS_IOPORT +/* + * Generic iomap devres + */ +static void devm_ioport_map_release(struct device *dev, void *res) +{ + ioport_unmap(*(void __iomem **)res); +} + +static int devm_ioport_map_match(struct device *dev, void *res, + void *match_data) +{ + return *(void **)res == match_data; +} + +/** + * devm_ioport_map - Managed ioport_map() + * @dev: Generic device to map ioport for + * @port: Port to map + * @nr: Number of ports to map + * + * Managed ioport_map(). Map is automatically unmapped on driver + * detach. + */ +void __iomem * devm_ioport_map(struct device *dev, unsigned long port, + unsigned int nr) +{ + void __iomem **ptr, *addr; + + ptr = devres_alloc(devm_ioport_map_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + addr = ioport_map(port, nr); + if (addr) { + *ptr = addr; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return addr; +} +EXPORT_SYMBOL(devm_ioport_map); + +/** + * devm_ioport_unmap - Managed ioport_unmap() + * @dev: Generic device to unmap for + * @addr: Address to unmap + * + * Managed ioport_unmap(). @addr must have been mapped using + * devm_ioport_map(). + */ +void devm_ioport_unmap(struct device *dev, void __iomem *addr) +{ + ioport_unmap(addr); + WARN_ON(devres_destroy(dev, devm_ioport_map_release, + devm_ioport_map_match, (void *)addr)); +} +EXPORT_SYMBOL(devm_ioport_unmap); + +#ifdef CONFIG_PCI +/* + * PCI iomap devres + */ +#define PCIM_IOMAP_MAX PCI_ROM_RESOURCE + +struct pcim_iomap_devres { + void __iomem *table[PCIM_IOMAP_MAX]; +}; + +static void pcim_iomap_release(struct device *gendev, void *res) +{ + struct pci_dev *dev = container_of(gendev, struct pci_dev, dev); + struct pcim_iomap_devres *this = res; + int i; + + for (i = 0; i < PCIM_IOMAP_MAX; i++) + if (this->table[i]) + pci_iounmap(dev, this->table[i]); +} + +/** + * pcim_iomap_table - access iomap allocation table + * @pdev: PCI device to access iomap table for + * + * Access iomap allocation table for @dev. If iomap table doesn't + * exist and @pdev is managed, it will be allocated. All iomaps + * recorded in the iomap table are automatically unmapped on driver + * detach. + * + * This function might sleep when the table is first allocated but can + * be safely called without context and guaranteed to succed once + * allocated. + */ +void __iomem * const * pcim_iomap_table(struct pci_dev *pdev) +{ + struct pcim_iomap_devres *dr, *new_dr; + + dr = devres_find(&pdev->dev, pcim_iomap_release, NULL, NULL); + if (dr) + return dr->table; + + new_dr = devres_alloc(pcim_iomap_release, sizeof(*new_dr), GFP_KERNEL); + if (!new_dr) + return NULL; + dr = devres_get(&pdev->dev, new_dr, NULL, NULL); + return dr->table; +} +EXPORT_SYMBOL(pcim_iomap_table); + +/** + * pcim_iomap - Managed pcim_iomap() + * @pdev: PCI device to iomap for + * @bar: BAR to iomap + * @maxlen: Maximum length of iomap + * + * Managed pci_iomap(). Map is automatically unmapped on driver + * detach. + */ +void __iomem * pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen) +{ + void __iomem **tbl; + + BUG_ON(bar >= PCIM_IOMAP_MAX); + + tbl = (void __iomem **)pcim_iomap_table(pdev); + if (!tbl || tbl[bar]) /* duplicate mappings not allowed */ + return NULL; + + tbl[bar] = pci_iomap(pdev, bar, maxlen); + return tbl[bar]; +} +EXPORT_SYMBOL(pcim_iomap); + +/** + * pcim_iounmap - Managed pci_iounmap() + * @pdev: PCI device to iounmap for + * @addr: Address to unmap + * + * Managed pci_iounmap(). @addr must have been mapped using pcim_iomap(). + */ +void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr) +{ + void __iomem **tbl; + int i; + + pci_iounmap(pdev, addr); + + tbl = (void __iomem **)pcim_iomap_table(pdev); + BUG_ON(!tbl); + + for (i = 0; i < PCIM_IOMAP_MAX; i++) + if (tbl[i] == addr) { + tbl[i] = NULL; + return; + } + WARN_ON(1); +} +EXPORT_SYMBOL(pcim_iounmap); + +/** + * pcim_iomap_regions - Request and iomap PCI BARs + * @pdev: PCI device to map IO resources for + * @mask: Mask of BARs to request and iomap + * @name: Name used when requesting regions + * + * Request and iomap regions specified by @mask. + */ +int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name) +{ + void __iomem * const *iomap; + int i, rc; + + iomap = pcim_iomap_table(pdev); + if (!iomap) + return -ENOMEM; + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + unsigned long len; + + if (!(mask & (1 << i))) + continue; + + rc = -EINVAL; + len = pci_resource_len(pdev, i); + if (!len) + goto err_inval; + + rc = pci_request_region(pdev, i, name); + if (rc) + goto err_inval; + + rc = -ENOMEM; + if (!pcim_iomap(pdev, i, 0)) + goto err_region; + } + + return 0; + + err_region: + pci_release_region(pdev, i); + err_inval: + while (--i >= 0) { + if (!(mask & (1 << i))) + continue; + pcim_iounmap(pdev, iomap[i]); + pci_release_region(pdev, i); + } + + return rc; +} +EXPORT_SYMBOL(pcim_iomap_regions); + +/** + * pcim_iounmap_regions - Unmap and release PCI BARs + * @pdev: PCI device to map IO resources for + * @mask: Mask of BARs to unmap and release + * + * Unamp and release regions specified by @mask. + */ +void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask) +{ + void __iomem * const *iomap; + int i; + + iomap = pcim_iomap_table(pdev); + if (!iomap) + return; + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (!(mask & (1 << i))) + continue; + + pcim_iounmap(pdev, iomap[i]); + pci_release_region(pdev, i); + } +} +EXPORT_SYMBOL(pcim_iounmap_regions); +#endif +#endif diff --git a/lib/div64.c b/lib/div64.c index 365719f..b71cf93 100644 --- a/lib/div64.c +++ b/lib/div64.c @@ -23,7 +23,7 @@ /* Not needed on 64bit architectures */ #if BITS_PER_LONG == 32 -uint32_t __div64_32(uint64_t *n, uint32_t base) +uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base) { uint64_t rem = *n; uint64_t b = base; @@ -58,4 +58,24 @@ uint32_t __div64_32(uint64_t *n, uint32_t base) EXPORT_SYMBOL(__div64_32); +/* 64bit divisor, dividend and result. dynamic precision */ +uint64_t div64_64(uint64_t dividend, uint64_t divisor) +{ + uint32_t high, d; + + high = divisor >> 32; + if (high) { + unsigned int shift = fls(high); + + d = divisor >> shift; + dividend >>= shift; + } else + d = divisor; + + do_div(dividend, d); + + return dividend; +} +EXPORT_SYMBOL(div64_64); + #endif /* BITS_PER_LONG == 32 */ diff --git a/lib/fault-inject.c b/lib/fault-inject.c index b5a90fc..0fabd12 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -55,7 +55,7 @@ static bool fail_task(struct fault_attr *attr, struct task_struct *task) #define MAX_STACK_TRACE_DEPTH 32 -#if defined(CONFIG_STACKTRACE) +#ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER static bool fail_stacktrace(struct fault_attr *attr) { @@ -90,17 +90,10 @@ static bool fail_stacktrace(struct fault_attr *attr) static inline bool fail_stacktrace(struct fault_attr *attr) { - static bool firsttime = true; - - if (firsttime) { - printk(KERN_WARNING - "This architecture does not implement save_stack_trace()\n"); - firsttime = false; - } - return false; + return true; } -#endif +#endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ /* * This code is stolen from failmalloc-1.0 @@ -217,6 +210,8 @@ void cleanup_fault_attr_dentries(struct fault_attr *attr) debugfs_remove(attr->dentries.task_filter_file); attr->dentries.task_filter_file = NULL; +#ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER + debugfs_remove(attr->dentries.stacktrace_depth_file); attr->dentries.stacktrace_depth_file = NULL; @@ -232,6 +227,8 @@ void cleanup_fault_attr_dentries(struct fault_attr *attr) debugfs_remove(attr->dentries.reject_end_file); attr->dentries.reject_end_file = NULL; +#endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ + if (attr->dentries.dir) WARN_ON(!simple_empty(attr->dentries.dir)); @@ -269,6 +266,13 @@ int init_fault_attr_dentries(struct fault_attr *attr, const char *name) attr->dentries.task_filter_file = debugfs_create_bool("task-filter", mode, dir, &attr->task_filter); + if (!attr->dentries.probability_file || !attr->dentries.interval_file || + !attr->dentries.times_file || !attr->dentries.space_file || + !attr->dentries.verbose_file || !attr->dentries.task_filter_file) + goto fail; + +#ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER + attr->dentries.stacktrace_depth_file = debugfs_create_ul_MAX_STACK_TRACE_DEPTH( "stacktrace-depth", mode, dir, &attr->stacktrace_depth); @@ -285,18 +289,15 @@ int init_fault_attr_dentries(struct fault_attr *attr, const char *name) attr->dentries.reject_end_file = debugfs_create_ul("reject-end", mode, dir, &attr->reject_end); - - if (!attr->dentries.probability_file || !attr->dentries.interval_file - || !attr->dentries.times_file || !attr->dentries.space_file - || !attr->dentries.verbose_file || !attr->dentries.task_filter_file - || !attr->dentries.stacktrace_depth_file - || !attr->dentries.require_start_file - || !attr->dentries.require_end_file - || !attr->dentries.reject_start_file - || !attr->dentries.reject_end_file - ) + if (!attr->dentries.stacktrace_depth_file || + !attr->dentries.require_start_file || + !attr->dentries.require_end_file || + !attr->dentries.reject_start_file || + !attr->dentries.reject_end_file) goto fail; +#endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ + return 0; fail: cleanup_fault_attr_dentries(attr); diff --git a/lib/genalloc.c b/lib/genalloc.c index 75ae68c..eb7c2ba 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -148,7 +148,7 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) addr = chunk->start_addr + ((unsigned long)start_bit << order); while (nbits--) - __set_bit(start_bit++, &chunk->bits); + __set_bit(start_bit++, chunk->bits); spin_unlock_irqrestore(&chunk->lock, flags); read_unlock(&pool->lock); return addr; @@ -187,7 +187,7 @@ void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size) spin_lock_irqsave(&chunk->lock, flags); bit = (addr - chunk->start_addr) >> order; while (nbits--) - __clear_bit(bit++, &chunk->bits); + __clear_bit(bit++, chunk->bits); spin_unlock_irqrestore(&chunk->lock, flags); break; } @@ -329,8 +329,8 @@ static void sub_remove(struct idr *idp, int shift, int id) /** * idr_remove - remove the given id and free it's slot - * idp: idr handle - * id: uniqueue key + * @idp: idr handle + * @id: unique key */ void idr_remove(struct idr *idp, int id) { diff --git a/lib/iomap.c b/lib/iomap.c index d6ccdd8..4d43f37 100644 --- a/lib/iomap.c +++ b/lib/iomap.c @@ -4,8 +4,9 @@ * (C) Copyright 2004 Linus Torvalds */ #include <linux/pci.h> +#include <linux/io.h> + #include <linux/module.h> -#include <asm/io.h> /* * Read/write from/to an (offsettable) iomem cookie. It might be a PIO diff --git a/lib/kobject.c b/lib/kobject.c index 7ce6dc1..cecf2fb 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -44,11 +44,11 @@ static int populate_dir(struct kobject * kobj) return error; } -static int create_dir(struct kobject * kobj) +static int create_dir(struct kobject * kobj, struct dentry *shadow_parent) { int error = 0; if (kobject_name(kobj)) { - error = sysfs_create_dir(kobj); + error = sysfs_create_dir(kobj, shadow_parent); if (!error) { if ((error = populate_dir(kobj))) sysfs_remove_dir(kobj); @@ -97,11 +97,12 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length) } /** - * kobject_get_path - generate and return the path associated with a given kobj - * and kset pair. The result must be freed by the caller with kfree(). + * kobject_get_path - generate and return the path associated with a given kobj and kset pair. * * @kobj: kobject in question, with which to build the path * @gfp_mask: the allocation type used to allocate the path + * + * The result must be freed by the caller with kfree(). */ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) { @@ -126,6 +127,8 @@ EXPORT_SYMBOL_GPL(kobject_get_path); */ void kobject_init(struct kobject * kobj) { + if (!kobj) + return; kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); init_waitqueue_head(&kobj->poll); @@ -154,11 +157,12 @@ static void unlink(struct kobject * kobj) } /** - * kobject_add - add an object to the hierarchy. + * kobject_shadow_add - add an object to the hierarchy. * @kobj: object. + * @shadow_parent: sysfs directory to add to. */ -int kobject_add(struct kobject * kobj) +int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent) { int error = 0; struct kobject * parent; @@ -167,9 +171,10 @@ int kobject_add(struct kobject * kobj) return -ENOENT; if (!kobj->k_name) kobj->k_name = kobj->name; - if (!kobj->k_name) { + if (!*kobj->k_name) { pr_debug("kobject attempted to be registered with no name!\n"); WARN_ON(1); + kobject_put(kobj); return -EINVAL; } parent = kobject_get(kobj->parent); @@ -186,15 +191,14 @@ int kobject_add(struct kobject * kobj) list_add_tail(&kobj->entry,&kobj->kset->list); spin_unlock(&kobj->kset->list_lock); + kobj->parent = parent; } - kobj->parent = parent; - error = create_dir(kobj); + error = create_dir(kobj, shadow_parent); if (error) { /* unlink does the kobject_put() for us */ unlink(kobj); - if (parent) - kobject_put(parent); + kobject_put(parent); /* be noisy on error issues */ if (error == -EEXIST) @@ -211,6 +215,15 @@ int kobject_add(struct kobject * kobj) return error; } +/** + * kobject_add - add an object to the hierarchy. + * @kobj: object. + */ +int kobject_add(struct kobject * kobj) +{ + return kobject_shadow_add(kobj, NULL); +} + /** * kobject_register - initialize and add an object. @@ -299,20 +312,73 @@ EXPORT_SYMBOL(kobject_set_name); int kobject_rename(struct kobject * kobj, const char *new_name) { int error = 0; + const char *devpath = NULL; + char *devpath_string = NULL; + char *envp[2]; kobj = kobject_get(kobj); if (!kobj) return -EINVAL; - error = sysfs_rename_dir(kobj, new_name); + if (!kobj->parent) + return -EINVAL; + + devpath = kobject_get_path(kobj, GFP_KERNEL); + if (!devpath) { + error = -ENOMEM; + goto out; + } + devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL); + if (!devpath_string) { + error = -ENOMEM; + goto out; + } + sprintf(devpath_string, "DEVPATH_OLD=%s", devpath); + envp[0] = devpath_string; + envp[1] = NULL; + /* Note : if we want to send the new name alone, not the full path, + * we could probably use kobject_name(kobj); */ + + error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name); + + /* This function is mostly/only used for network interface. + * Some hotplug package track interfaces by their name and + * therefore want to know when the name is changed by the user. */ + if (!error) + kobject_uevent_env(kobj, KOBJ_MOVE, envp); + +out: + kfree(devpath_string); + kfree(devpath); kobject_put(kobj); return error; } /** - * kobject_move - move object to another parent + * kobject_rename - change the name of an object * @kobj: object in question. * @new_parent: object's new parent + * @new_name: object's new name + */ + +int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent, + const char *new_name) +{ + int error = 0; + + kobj = kobject_get(kobj); + if (!kobj) + return -EINVAL; + error = sysfs_rename_dir(kobj, new_parent, new_name); + kobject_put(kobj); + + return error; +} + +/** + * kobject_move - move object to another parent + * @kobj: object in question. + * @new_parent: object's new parent (can be NULL) */ int kobject_move(struct kobject *kobj, struct kobject *new_parent) @@ -328,8 +394,8 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent) return -EINVAL; new_parent = kobject_get(new_parent); if (!new_parent) { - error = -EINVAL; - goto out; + if (kobj->kset) + new_parent = kobject_get(&kobj->kset->kobj); } /* old object path */ devpath = kobject_get_path(kobj, GFP_KERNEL); @@ -350,9 +416,11 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent) goto out; old_parent = kobj->parent; kobj->parent = new_parent; + new_parent = NULL; kobject_put(old_parent); kobject_uevent_env(kobj, KOBJ_MOVE, envp); out: + kobject_put(new_parent); kobject_put(kobj); kfree(devpath_string); kfree(devpath); @@ -366,6 +434,8 @@ out: void kobject_del(struct kobject * kobj) { + if (!kobj) + return; sysfs_remove_dir(kobj); unlink(kobj); } @@ -377,6 +447,8 @@ void kobject_del(struct kobject * kobj) void kobject_unregister(struct kobject * kobj) { + if (!kobj) + return; pr_debug("kobject %s: unregistering\n",kobject_name(kobj)); kobject_uevent(kobj, KOBJ_REMOVE); kobject_del(kobj); @@ -414,8 +486,7 @@ void kobject_cleanup(struct kobject * kobj) t->release(kobj); if (s) kset_put(s); - if (parent) - kobject_put(parent); + kobject_put(parent); } static void kobject_release(struct kref *kref) @@ -448,13 +519,15 @@ static struct kobj_type dir_ktype = { }; /** - * kobject_add_dir - add sub directory of object. + * kobject_kset_add_dir - add sub directory of object. + * @kset: kset the directory is belongs to. * @parent: object in which a directory is created. * @name: directory name. * * Add a plain directory object as child of given object. */ -struct kobject *kobject_add_dir(struct kobject *parent, const char *name) +struct kobject *kobject_kset_add_dir(struct kset *kset, + struct kobject *parent, const char *name) { struct kobject *k; int ret; @@ -466,13 +539,14 @@ struct kobject *kobject_add_dir(struct kobject *parent, const char *name) if (!k) return NULL; + k->kset = kset; k->parent = parent; k->ktype = &dir_ktype; kobject_set_name(k, name); ret = kobject_register(k); if (ret < 0) { - printk(KERN_WARNING "kobject_add_dir: " - "kobject_register error: %d\n", ret); + printk(KERN_WARNING "%s: kobject_register error: %d\n", + __func__, ret); kobject_del(k); return NULL; } @@ -481,6 +555,18 @@ struct kobject *kobject_add_dir(struct kobject *parent, const char *name) } /** + * kobject_add_dir - add sub directory of object. + * @parent: object in which a directory is created. + * @name: directory name. + * + * Add a plain directory object as child of given object. + */ +struct kobject *kobject_add_dir(struct kobject *parent, const char *name) +{ + return kobject_kset_add_dir(NULL, parent, name); +} + +/** * kset_init - initialize a kset for use * @k: kset */ @@ -523,6 +609,8 @@ int kset_add(struct kset * k) int kset_register(struct kset * k) { + if (!k) + return -EINVAL; kset_init(k); return kset_add(k); } @@ -535,6 +623,8 @@ int kset_register(struct kset * k) void kset_unregister(struct kset * k) { + if (!k) + return; kobject_unregister(&k->kobj); } @@ -569,7 +659,6 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name) void subsystem_init(struct subsystem * s) { - init_rwsem(&s->rwsem); kset_init(&s->kset); } @@ -578,14 +667,16 @@ void subsystem_init(struct subsystem * s) * @s: the subsystem we're registering. * * Once we register the subsystem, we want to make sure that - * the kset points back to this subsystem for correct usage of - * the rwsem. + * the kset points back to this subsystem. */ int subsystem_register(struct subsystem * s) { int error; + if (!s) + return -EINVAL; + subsystem_init(s); pr_debug("subsystem %s: registering\n",s->kset.kobj.name); @@ -598,6 +689,8 @@ int subsystem_register(struct subsystem * s) void subsystem_unregister(struct subsystem * s) { + if (!s) + return; pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name); kset_unregister(&s->kset); } @@ -612,6 +705,10 @@ void subsystem_unregister(struct subsystem * s) int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) { int error = 0; + + if (!s || !a) + return -EINVAL; + if (subsys_get(s)) { error = sysfs_create_file(&s->kset.kobj,&a->attr); subsys_put(s); diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 84272ed..12e311d 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -42,10 +42,6 @@ static char *action_to_string(enum kobject_action action) return "remove"; case KOBJ_CHANGE: return "change"; - case KOBJ_MOUNT: - return "mount"; - case KOBJ_UMOUNT: - return "umount"; case KOBJ_OFFLINE: return "offline"; case KOBJ_ONLINE: @@ -95,10 +91,8 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, /* search the kset we belong to */ top_kobj = kobj; - if (!top_kobj->kset && top_kobj->parent) { - do { - top_kobj = top_kobj->parent; - } while (!top_kobj->kset && top_kobj->parent); + while (!top_kobj->kset && top_kobj->parent) { + top_kobj = top_kobj->parent; } if (!top_kobj->kset) { pr_debug("kobject attempted to send uevent without kset!\n"); @@ -115,6 +109,16 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, return 0; } + /* originating subsystem */ + if (uevent_ops && uevent_ops->name) + subsystem = uevent_ops->name(kset, kobj); + else + subsystem = kobject_name(&kset->kobj); + if (!subsystem) { + pr_debug("unset subsytem caused the event to drop!\n"); + return 0; + } + /* environment index */ envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL); if (!envp) @@ -134,12 +138,6 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, goto exit; } - /* originating subsystem */ - if (uevent_ops && uevent_ops->name) - subsystem = uevent_ops->name(kset, kobj); - else - subsystem = kobject_name(&kset->kobj); - /* event environemnt for helper process only */ envp[i++] = "HOME=/"; envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; @@ -293,7 +291,7 @@ EXPORT_SYMBOL_GPL(add_uevent_var); static int __init kobject_uevent_init(void) { uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL, - THIS_MODULE); + NULL, THIS_MODULE); if (!uevent_sock) { printk(KERN_ERR @@ -21,6 +21,7 @@ void kref_init(struct kref *kref) { atomic_set(&kref->refcount,1); + smp_mb(); } /** @@ -31,6 +32,7 @@ void kref_get(struct kref *kref) { WARN_ON(!atomic_read(&kref->refcount)); atomic_inc(&kref->refcount); + smp_mb__after_atomic_inc(); } /** @@ -20,8 +20,8 @@ #define K3 0x8F1BBCDCL /* Rounds 40-59: sqrt(5) * 2^30 */ #define K4 0xCA62C1D6L /* Rounds 60-79: sqrt(10) * 2^30 */ -/* - * sha_transform: single block SHA1 transform +/** + * sha_transform - single block SHA1 transform * * @digest: 160 bit digest to update * @data: 512 bits of data to hash @@ -80,9 +80,8 @@ void sha_transform(__u32 *digest, const char *in, __u32 *W) } EXPORT_SYMBOL(sha_transform); -/* - * sha_init: initialize the vectors for a SHA1 digest - * +/** + * sha_init - initialize the vectors for a SHA1 digest * @buf: vector to initialize */ void sha_init(__u32 *buf) @@ -27,7 +27,7 @@ static void generic_swap(void *a, void *b, int size) } while (--size > 0); } -/* +/** * sort - sort an array of elements * @base: pointer to data to sort * @num: number of elements diff --git a/lib/string.c b/lib/string.c index a485d75..5efafed 100644 --- a/lib/string.c +++ b/lib/string.c @@ -60,6 +60,34 @@ int strnicmp(const char *s1, const char *s2, size_t len) EXPORT_SYMBOL(strnicmp); #endif +#ifndef __HAVE_ARCH_STRCASECMP +int strcasecmp(const char *s1, const char *s2) +{ + int c1, c2; + + do { + c1 = tolower(*s1++); + c2 = tolower(*s2++); + } while (c1 == c2 && c1 != 0); + return c1 - c2; +} +EXPORT_SYMBOL(strcasecmp); +#endif + +#ifndef __HAVE_ARCH_STRNCASECMP +int strncasecmp(const char *s1, const char *s2, size_t n) +{ + int c1, c2; + + do { + c1 = tolower(*s1++); + c2 = tolower(*s2++); + } while ((--n > 0) && c1 == c2 && c1 != 0); + return c1 - c2; +} +EXPORT_SYMBOL(strncasecmp); +#endif + #ifndef __HAVE_ARCH_STRCPY /** * strcpy - Copy a %NUL terminated string @@ -160,7 +188,7 @@ EXPORT_SYMBOL(strcat); * @src: The string to append to it * @count: The maximum numbers of bytes to copy * - * Note that in contrast to strncpy, strncat ensures the result is + * Note that in contrast to strncpy(), strncat() ensures the result is * terminated. */ char *strncat(char *dest, const char *src, size_t count) @@ -366,8 +394,7 @@ EXPORT_SYMBOL(strnlen); #ifndef __HAVE_ARCH_STRSPN /** - * strspn - Calculate the length of the initial substring of @s which only - * contain letters in @accept + * strspn - Calculate the length of the initial substring of @s which only contain letters in @accept * @s: The string to be searched * @accept: The string to search for */ @@ -394,8 +421,7 @@ EXPORT_SYMBOL(strspn); #ifndef __HAVE_ARCH_STRCSPN /** - * strcspn - Calculate the length of the initial substring of @s which does - * not contain letters in @reject + * strcspn - Calculate the length of the initial substring of @s which does not contain letters in @reject * @s: The string to be searched * @reject: The string to avoid */ diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 1062578..9970e55 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -1,7 +1,7 @@ /* * Dynamic DMA mapping support. * - * This implementation is for IA-64 and EM64T platforms that do not support + * This implementation is a fallback for platforms that do not support * I/O TLBs (aka DMA address translation hardware). * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com> * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com> @@ -36,7 +36,7 @@ ( (val) & ( (align) - 1))) #define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset) -#define SG_ENT_PHYS_ADDRESS(SG) virt_to_phys(SG_ENT_VIRT_ADDRESS(SG)) +#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg)) /* * Maximum allowable number of contiguous slabs to map, @@ -129,23 +129,25 @@ __setup("swiotlb=", setup_io_tlb_npages); * Statically reserve bounce buffer space and initialize bounce buffer data * structures for the software IO TLB used to implement the DMA API. */ -void -swiotlb_init_with_default_size (size_t default_size) +void __init +swiotlb_init_with_default_size(size_t default_size) { - unsigned long i; + unsigned long i, bytes; if (!io_tlb_nslabs) { io_tlb_nslabs = (default_size >> IO_TLB_SHIFT); io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE); } + bytes = io_tlb_nslabs << IO_TLB_SHIFT; + /* * Get IO TLB memory from the low pages */ - io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT)); + io_tlb_start = alloc_bootmem_low_pages(bytes); if (!io_tlb_start) panic("Cannot allocate SWIOTLB buffer"); - io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT); + io_tlb_end = io_tlb_start + bytes; /* * Allocate and initialize the free list array. This array is used @@ -162,12 +164,15 @@ swiotlb_init_with_default_size (size_t default_size) * Get the overflow emergency buffer */ io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); + if (!io_tlb_overflow_buffer) + panic("Cannot allocate SWIOTLB overflow buffer!\n"); + printk(KERN_INFO "Placing software IO TLB between 0x%lx - 0x%lx\n", - virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end)); + virt_to_bus(io_tlb_start), virt_to_bus(io_tlb_end)); } -void -swiotlb_init (void) +void __init +swiotlb_init(void) { swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */ } @@ -178,9 +183,9 @@ swiotlb_init (void) * This should be just like above, but with some error catching. */ int -swiotlb_late_init_with_default_size (size_t default_size) +swiotlb_late_init_with_default_size(size_t default_size) { - unsigned long i, req_nslabs = io_tlb_nslabs; + unsigned long i, bytes, req_nslabs = io_tlb_nslabs; unsigned int order; if (!io_tlb_nslabs) { @@ -191,8 +196,9 @@ swiotlb_late_init_with_default_size (size_t default_size) /* * Get IO TLB memory from the low pages */ - order = get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT)); + order = get_order(io_tlb_nslabs << IO_TLB_SHIFT); io_tlb_nslabs = SLABS_PER_PAGE << order; + bytes = io_tlb_nslabs << IO_TLB_SHIFT; while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) { io_tlb_start = (char *)__get_free_pages(GFP_DMA | __GFP_NOWARN, @@ -205,13 +211,14 @@ swiotlb_late_init_with_default_size (size_t default_size) if (!io_tlb_start) goto cleanup1; - if (order != get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT))) { + if (order != get_order(bytes)) { printk(KERN_WARNING "Warning: only able to allocate %ld MB " "for software IO TLB\n", (PAGE_SIZE << order) >> 20); io_tlb_nslabs = SLABS_PER_PAGE << order; + bytes = io_tlb_nslabs << IO_TLB_SHIFT; } - io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT); - memset(io_tlb_start, 0, io_tlb_nslabs * (1 << IO_TLB_SHIFT)); + io_tlb_end = io_tlb_start + bytes; + memset(io_tlb_start, 0, bytes); /* * Allocate and initialize the free list array. This array is used @@ -242,9 +249,9 @@ swiotlb_late_init_with_default_size (size_t default_size) if (!io_tlb_overflow_buffer) goto cleanup4; - printk(KERN_INFO "Placing %ldMB software IO TLB between 0x%lx - " - "0x%lx\n", (io_tlb_nslabs * (1 << IO_TLB_SHIFT)) >> 20, - virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end)); + printk(KERN_INFO "Placing %luMB software IO TLB between 0x%lx - " + "0x%lx\n", bytes >> 20, + virt_to_bus(io_tlb_start), virt_to_bus(io_tlb_end)); return 0; @@ -256,8 +263,8 @@ cleanup3: free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs * sizeof(int))); io_tlb_list = NULL; - io_tlb_end = NULL; cleanup2: + io_tlb_end = NULL; free_pages((unsigned long)io_tlb_start, order); io_tlb_start = NULL; cleanup1: @@ -265,7 +272,7 @@ cleanup1: return -ENOMEM; } -static inline int +static int address_needs_mapping(struct device *hwdev, dma_addr_t addr) { dma_addr_t mask = 0xffffffff; @@ -433,7 +440,7 @@ void * swiotlb_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags) { - unsigned long dev_addr; + dma_addr_t dev_addr; void *ret; int order = get_order(size); @@ -445,7 +452,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, flags |= GFP_DMA; ret = (void *)__get_free_pages(flags, order); - if (ret && address_needs_mapping(hwdev, virt_to_phys(ret))) { + if (ret && address_needs_mapping(hwdev, virt_to_bus(ret))) { /* * The allocated memory isn't reachable by the device. * Fall back on swiotlb_map_single(). @@ -465,16 +472,17 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, if (swiotlb_dma_mapping_error(handle)) return NULL; - ret = phys_to_virt(handle); + ret = bus_to_virt(handle); } memset(ret, 0, size); - dev_addr = virt_to_phys(ret); + dev_addr = virt_to_bus(ret); /* Confirm address can be DMA'd by device */ if (address_needs_mapping(hwdev, dev_addr)) { - printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016lx\n", - (unsigned long long)*hwdev->dma_mask, dev_addr); + printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n", + (unsigned long long)*hwdev->dma_mask, + (unsigned long long)dev_addr); panic("swiotlb_alloc_coherent: allocated memory is out of " "range for device"); } @@ -504,7 +512,7 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) * When the mapping is small enough return a static buffer to limit * the damage, or panic when the transfer is too big. */ - printk(KERN_ERR "DMA: Out of SW-IOMMU space for %lu bytes at " + printk(KERN_ERR "DMA: Out of SW-IOMMU space for %zu bytes at " "device %s\n", size, dev ? dev->bus_id : "?"); if (size > io_tlb_overflow && do_panic) { @@ -525,7 +533,7 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) { - unsigned long dev_addr = virt_to_phys(ptr); + dma_addr_t dev_addr = virt_to_bus(ptr); void *map; BUG_ON(dir == DMA_NONE); @@ -546,7 +554,7 @@ swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) map = io_tlb_overflow_buffer; } - dev_addr = virt_to_phys(map); + dev_addr = virt_to_bus(map); /* * Ensure that the address returned is DMA'ble @@ -558,25 +566,6 @@ swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) } /* - * Since DMA is i-cache coherent, any (complete) pages that were written via - * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to - * flush them when they get mapped into an executable vm-area. - */ -static void -mark_clean(void *addr, size_t size) -{ - unsigned long pg_addr, end; - - pg_addr = PAGE_ALIGN((unsigned long) addr); - end = (unsigned long) addr + size; - while (pg_addr + PAGE_SIZE <= end) { - struct page *page = virt_to_page(pg_addr); - set_bit(PG_arch_1, &page->flags); - pg_addr += PAGE_SIZE; - } -} - -/* * Unmap a single streaming mode DMA translation. The dma_addr and size must * match what was provided for in a previous swiotlb_map_single call. All * other usages are undefined. @@ -588,13 +577,13 @@ void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) { - char *dma_addr = phys_to_virt(dev_addr); + char *dma_addr = bus_to_virt(dev_addr); BUG_ON(dir == DMA_NONE); if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) unmap_single(hwdev, dma_addr, size, dir); else if (dir == DMA_FROM_DEVICE) - mark_clean(dma_addr, size); + dma_mark_clean(dma_addr, size); } /* @@ -607,17 +596,17 @@ swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, * address back to the card, you must first perform a * swiotlb_dma_sync_for_device, and then the device again owns the buffer */ -static inline void +static void swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir, int target) { - char *dma_addr = phys_to_virt(dev_addr); + char *dma_addr = bus_to_virt(dev_addr); BUG_ON(dir == DMA_NONE); if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) sync_single(hwdev, dma_addr, size, dir, target); else if (dir == DMA_FROM_DEVICE) - mark_clean(dma_addr, size); + dma_mark_clean(dma_addr, size); } void @@ -637,18 +626,18 @@ swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, /* * Same as above, but for a sub-range of the mapping. */ -static inline void +static void swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, size_t size, int dir, int target) { - char *dma_addr = phys_to_virt(dev_addr) + offset; + char *dma_addr = bus_to_virt(dev_addr) + offset; BUG_ON(dir == DMA_NONE); if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) sync_single(hwdev, dma_addr, size, dir, target); else if (dir == DMA_FROM_DEVICE) - mark_clean(dma_addr, size); + dma_mark_clean(dma_addr, size); } void @@ -688,17 +677,16 @@ swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, int dir) { void *addr; - unsigned long dev_addr; + dma_addr_t dev_addr; int i; BUG_ON(dir == DMA_NONE); for (i = 0; i < nelems; i++, sg++) { addr = SG_ENT_VIRT_ADDRESS(sg); - dev_addr = virt_to_phys(addr); + dev_addr = virt_to_bus(addr); if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) { void *map = map_single(hwdev, addr, sg->length, dir); - sg->dma_address = virt_to_bus(map); if (!map) { /* Don't panic here, we expect map_sg users to do proper error handling. */ @@ -707,6 +695,7 @@ swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, sg[0].dma_length = 0; return 0; } + sg->dma_address = virt_to_bus(map); } else sg->dma_address = dev_addr; sg->dma_length = sg->length; @@ -728,9 +717,10 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems, for (i = 0; i < nelems; i++, sg++) if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) - unmap_single(hwdev, (void *) phys_to_virt(sg->dma_address), sg->dma_length, dir); + unmap_single(hwdev, bus_to_virt(sg->dma_address), + sg->dma_length, dir); else if (dir == DMA_FROM_DEVICE) - mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); + dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); } /* @@ -740,7 +730,7 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems, * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules * and usage. */ -static inline void +static void swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg, int nelems, int dir, int target) { @@ -750,8 +740,10 @@ swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg, for (i = 0; i < nelems; i++, sg++) if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) - sync_single(hwdev, (void *) sg->dma_address, + sync_single(hwdev, bus_to_virt(sg->dma_address), sg->dma_length, dir, target); + else if (dir == DMA_FROM_DEVICE) + dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); } void @@ -771,7 +763,7 @@ swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int swiotlb_dma_mapping_error(dma_addr_t dma_addr) { - return (dma_addr == virt_to_phys(io_tlb_overflow_buffer)); + return (dma_addr == virt_to_bus(io_tlb_overflow_buffer)); } /* @@ -781,9 +773,9 @@ swiotlb_dma_mapping_error(dma_addr_t dma_addr) * this function. */ int -swiotlb_dma_supported (struct device *hwdev, u64 mask) +swiotlb_dma_supported(struct device *hwdev, u64 mask) { - return (virt_to_phys (io_tlb_end) - 1) <= mask; + return virt_to_bus(io_tlb_end - 1) <= mask; } EXPORT_SYMBOL(swiotlb_init); diff --git a/lib/textsearch.c b/lib/textsearch.c index 98bcadc..88c98a2 100644 --- a/lib/textsearch.c +++ b/lib/textsearch.c @@ -40,7 +40,7 @@ * configuration according to the specified parameters. * (3) User starts the search(es) by calling _find() or _next() to * fetch subsequent occurrences. A state variable is provided - * to the algorihtm to store persistent variables. + * to the algorithm to store persistent variables. * (4) Core eventually resets the search offset and forwards the find() * request to the algorithm. * (5) Algorithm calls get_next_block() provided by the user continously @@ -218,7 +218,7 @@ static unsigned int get_linear_data(unsigned int consumed, const u8 **dst, * Call textsearch_next() to retrieve subsequent matches. * * Returns the position of first occurrence of the pattern or - * UINT_MAX if no occurrence was found. + * %UINT_MAX if no occurrence was found. */ unsigned int textsearch_find_continuous(struct ts_config *conf, struct ts_state *state, diff --git a/lib/vsprintf.c b/lib/vsprintf.c index bed7229..b025864 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -247,12 +247,12 @@ static char * number(char * buf, char * end, unsigned long long num, int base, i * be generated for the given input, excluding the trailing * '\0', as per ISO C99. If you want to have the exact * number of characters written into @buf as return value - * (not including the trailing '\0'), use vscnprintf. If the + * (not including the trailing '\0'), use vscnprintf(). If the * return is greater than or equal to @size, the resulting * string is truncated. * * Call this function if you are already dealing with a va_list. - * You probably want snprintf instead. + * You probably want snprintf() instead. */ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { @@ -509,7 +509,7 @@ EXPORT_SYMBOL(vsnprintf); * returns 0. * * Call this function if you are already dealing with a va_list. - * You probably want scnprintf instead. + * You probably want scnprintf() instead. */ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) { @@ -554,8 +554,7 @@ EXPORT_SYMBOL(snprintf); * @...: Arguments for the format string * * The return value is the number of characters written into @buf not including - * the trailing '\0'. If @size is <= 0 the function returns 0. If the return is - * greater than or equal to @size, the resulting string is truncated. + * the trailing '\0'. If @size is <= 0 the function returns 0. */ int scnprintf(char * buf, size_t size, const char *fmt, ...) @@ -577,11 +576,11 @@ EXPORT_SYMBOL(scnprintf); * @args: Arguments for the format string * * The function returns the number of characters written - * into @buf. Use vsnprintf or vscnprintf in order to avoid + * into @buf. Use vsnprintf() or vscnprintf() in order to avoid * buffer overflows. * * Call this function if you are already dealing with a va_list. - * You probably want sprintf instead. + * You probably want sprintf() instead. */ int vsprintf(char *buf, const char *fmt, va_list args) { @@ -597,7 +596,7 @@ EXPORT_SYMBOL(vsprintf); * @...: Arguments for the format string * * The function returns the number of characters written - * into @buf. Use snprintf or scnprintf in order to avoid + * into @buf. Use snprintf() or scnprintf() in order to avoid * buffer overflows. */ int sprintf(char * buf, const char *fmt, ...) |