lkml.org 
[lkml]   [2004]   [Nov]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectSuspend 2 merge: 43/51: Utility functions.
    From
    Date
    These are the routines that I think could possibly be useful elsewhere
    too.

    - A snprintf routine that returns the number of bytes actually put into
    the buffer, not the number that would have been put in if the buffer was
    big enough.
    - Routine for finding a proc dir entry (we use it to find /proc/splash
    when)
    - Support routines for dynamically allocated pageflags. Save those
    precious bits!

    diff -ruN 834-utility-old/kernel/power/utility.c 834-utility-new/kernel/power/utility.c
    --- 834-utility-old/kernel/power/utility.c 1970-01-01 10:00:00.000000000 +1000
    +++ 834-utility-new/kernel/power/utility.c 2004-11-04 16:27:41.000000000 +1100
    @@ -0,0 +1,152 @@
    +/*
    + * kernel/power/utility.c
    + *
    + * Copyright (C) 2004 Nigel Cunningham <ncunningham@linuxmail.org>
    + *
    + * This file is released under the GPLv2.
    + *
    + * Routines that only suspend uses at the moment, but which might move
    + * when we merge because they're generic.
    + */
    +
    +#include <linux/kernel.h>
    +#include <linux/module.h>
    +#include <linux/mm.h>
    +#include <linux/proc_fs.h>
    +#include <asm/string.h>
    +
    +#include "pageflags.h"
    +
    +extern int suspend_snprintf(char * buffer, int buffer_size, const char *fmt, ...);
    +extern struct proc_dir_entry * find_proc_dir_entry(const char *name, struct proc_dir_entry *parent);
    +
    +/*
    + * suspend_snprintf
    + *
    + * Functionality : Print a string with parameters to a buffer of a
    + * limited size. Unlike vsnprintf, we return the number
    + * of bytes actually put in the buffer, not the number
    + * that would have been put in if it was big enough.
    + */
    +int suspend_snprintf(char * buffer, int buffer_size, const char *fmt, ...)
    +{
    + int result;
    + va_list args;
    +
    + if (!buffer_size) {
    + return 0;
    + }
    +
    + va_start(args, fmt);
    + result = vsnprintf(buffer, buffer_size, fmt, args);
    + va_end(args);
    +
    + if (result > buffer_size) {
    + return buffer_size;
    + }
    +
    + return result;
    +}
    +
    +/*
    + * find_proc_dir_entry.
    + *
    + * Based on remove_proc_entry.
    + * This will go shortly, once user space utilities
    + * are updated to look at /proc/suspend/all_settings.
    + */
    +
    +struct proc_dir_entry * find_proc_dir_entry(const char *name, struct proc_dir_entry *parent)
    +{
    + struct proc_dir_entry **p;
    + int len;
    +
    + len = strlen(name);
    + for (p = &parent->subdir; *p; p=&(*p)->next ) {
    + if (proc_match(len, name, *p)) {
    + return *p;
    + }
    + }
    + return NULL;
    +}
    +
    +/* ------------- Dynamically Allocated Page Flags --------------- */
    +
    +#define BITS_PER_PAGE (PAGE_SIZE * 8)
    +#define PAGES_PER_BITMAP ((max_mapnr + BITS_PER_PAGE - 1) / BITS_PER_PAGE)
    +#define BITMAP_ORDER (get_bitmask_order((PAGES_PER_BITMAP) - 1))
    +
    +/* clear_map
    + *
    + * Description: Clear an array used to store local page flags.
    + * Arguments: unsigned long *: The pagemap to be cleared.
    + */
    +
    +void clear_map(unsigned long * pagemap)
    +{
    + int size = (1 << BITMAP_ORDER) * PAGE_SIZE;
    +
    + memset(pagemap, 0, size);
    +}
    +
    +/* allocate_local_pageflags
    + *
    + * Description: Allocate a bitmap for local page flags.
    + * Arguments: unsigned long **: Pointer to the bitmap.
    + * int: Whether to set nosave flags for the
    + * newly allocated pages.
    + * Note: This looks suboptimal, but remember that we might be allocating
    + * the Nosave bitmap here.
    + */
    +int allocate_local_pageflags(unsigned long ** pagemap, int setnosave)
    +{
    + unsigned long * check;
    + int i;
    + if (*pagemap) {
    + printk("Error. Local pageflags map already allocated.\n");
    + clear_map(*pagemap);
    + } else {
    + check = (unsigned long *) __get_free_pages(GFP_ATOMIC,
    + BITMAP_ORDER);
    + if (!check) {
    + printk("Error. Unable to allocate memory for local page flags.");
    + return 1;
    + }
    + clear_map(check);
    + *pagemap = check;
    + if (setnosave) {
    + struct page * firstpage =
    + virt_to_page((unsigned long) check);
    + for (i = 0; i < (1 << BITMAP_ORDER); i++)
    + SetPageNosave(firstpage + i);
    + }
    + }
    + return 0;
    +}
    +
    +/* freemap
    + *
    + * Description: Free a local pageflags bitmap.
    + * Arguments: unsigned long **: Pointer to the bitmap being freed.
    + * Note: Map being freed might be Nosave.
    + */
    +int free_local_pageflags(unsigned long ** pagemap)
    +{
    + int i;
    + if (!*pagemap)
    + return 1;
    + else {
    + struct page * firstpage =
    + virt_to_page((unsigned long) *pagemap);
    + for (i = 0; i < (1 << BITMAP_ORDER); i++)
    + ClearPageNosave(firstpage + i);
    + free_pages((unsigned long) *pagemap, BITMAP_ORDER);
    + *pagemap = NULL;
    + return 0;
    + }
    +}
    +
    +EXPORT_SYMBOL(suspend_snprintf);
    +EXPORT_SYMBOL(allocate_local_pageflags);
    +EXPORT_SYMBOL(free_local_pageflags);
    +EXPORT_SYMBOL(find_proc_dir_entry);

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:08    [W:4.339 / U:0.280 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site