diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-16 08:11:54 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-16 08:11:54 -0700 |
commit | 7ea61767e41e2baedd6a968d13f56026522e1207 (patch) | |
tree | 45120513d73ab1d05897b00e4e10a7e875b142b6 /drivers/staging/hv/osd.c | |
parent | 0950efd1a1490e869d19ec631eed75ef57772f8b (diff) | |
parent | e9d599220b97e7d52311f6011c75ba0cfcb356fe (diff) | |
download | op-kernel-dev-7ea61767e41e2baedd6a968d13f56026522e1207.zip op-kernel-dev-7ea61767e41e2baedd6a968d13f56026522e1207.tar.gz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (641 commits)
Staging: remove sxg driver
Staging: remove heci driver
Staging: remove at76_usb wireless driver.
Staging: rspiusb: remove the driver
Staging: meilhaus: remove the drivers
Staging: remove me4000 driver.
Staging: line6: ffzb returns an unsigned integer
Staging: line6: pod.c: style cleanups
Staging: iio: introduce missing kfree
Staging: dream: introduce missing kfree
Staging: comedi: addi-data: NULL dereference of amcc in v_pci_card_list_init()
Staging: vt665x: fix built-in compiling
Staging: rt3090: enable NATIVE_WPA_SUPPLICANT_SUPPORT option
Staging: rt3090: port changes in WPA_MIX_PAIR_CIPHER to rt3090
Staging: rt3090: rename device from raX to wlanX
Staging: rt3090: remove possible conflict with rt2860
Staging: rt2860/rt2870/rt3070/rt3090: fix compiler warning on x86_64
Staging: rt2860: add new device ids
Staging: rt3090: add device id 1462:891a
Staging: asus_oled: Cleaned up checkpatch issues.
...
Diffstat (limited to 'drivers/staging/hv/osd.c')
-rw-r--r-- | drivers/staging/hv/osd.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c new file mode 100644 index 0000000..8fe543b --- /dev/null +++ b/drivers/staging/hv/osd.c @@ -0,0 +1,156 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang <haiyangz@microsoft.com> + * Hank Janssen <hjanssen@microsoft.com> + * + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/highmem.h> +#include <linux/vmalloc.h> +#include <linux/ioport.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/wait.h> +#include <linux/spinlock.h> +#include <linux/workqueue.h> +#include <linux/kernel.h> +#include <linux/jiffies.h> +#include <linux/delay.h> +#include <linux/time.h> +#include <linux/io.h> +#include <linux/bitops.h> +#include "osd.h" + +struct osd_callback_struct { + struct work_struct work; + void (*callback)(void *); + void *data; +}; + +void *osd_VirtualAllocExec(unsigned int size) +{ +#ifdef __x86_64__ + return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL_EXEC); +#else + return __vmalloc(size, GFP_KERNEL, + __pgprot(__PAGE_KERNEL & (~_PAGE_NX))); +#endif +} + +void *osd_PageAlloc(unsigned int count) +{ + void *p; + + p = (void *)__get_free_pages(GFP_KERNEL, get_order(count * PAGE_SIZE)); + if (p) + memset(p, 0, count * PAGE_SIZE); + return p; + + /* struct page* page = alloc_page(GFP_KERNEL|__GFP_ZERO); */ + /* void *p; */ + + /* BUGBUG: We need to use kmap in case we are in HIMEM region */ + /* p = page_address(page); */ + /* if (p) memset(p, 0, PAGE_SIZE); */ + /* return p; */ +} +EXPORT_SYMBOL_GPL(osd_PageAlloc); + +void osd_PageFree(void *page, unsigned int count) +{ + free_pages((unsigned long)page, get_order(count * PAGE_SIZE)); + /*struct page* p = virt_to_page(page); + __free_page(p);*/ +} +EXPORT_SYMBOL_GPL(osd_PageFree); + +struct osd_waitevent *osd_WaitEventCreate(void) +{ + struct osd_waitevent *wait = kmalloc(sizeof(struct osd_waitevent), + GFP_KERNEL); + if (!wait) + return NULL; + + wait->condition = 0; + init_waitqueue_head(&wait->event); + return wait; +} +EXPORT_SYMBOL_GPL(osd_WaitEventCreate); + +void osd_WaitEventSet(struct osd_waitevent *waitEvent) +{ + waitEvent->condition = 1; + wake_up_interruptible(&waitEvent->event); +} +EXPORT_SYMBOL_GPL(osd_WaitEventSet); + +int osd_WaitEventWait(struct osd_waitevent *waitEvent) +{ + int ret = 0; + + ret = wait_event_interruptible(waitEvent->event, + waitEvent->condition); + waitEvent->condition = 0; + return ret; +} +EXPORT_SYMBOL_GPL(osd_WaitEventWait); + +int osd_WaitEventWaitEx(struct osd_waitevent *waitEvent, u32 TimeoutInMs) +{ + int ret = 0; + + ret = wait_event_interruptible_timeout(waitEvent->event, + waitEvent->condition, + msecs_to_jiffies(TimeoutInMs)); + waitEvent->condition = 0; + return ret; +} +EXPORT_SYMBOL_GPL(osd_WaitEventWaitEx); + +static void osd_callback_work(struct work_struct *work) +{ + struct osd_callback_struct *cb = container_of(work, + struct osd_callback_struct, + work); + (cb->callback)(cb->data); + kfree(cb); +} + +int osd_schedule_callback(struct workqueue_struct *wq, + void (*func)(void *), + void *data) +{ + struct osd_callback_struct *cb; + + cb = kmalloc(sizeof(*cb), GFP_KERNEL); + if (!cb) { + printk(KERN_ERR "unable to allocate memory in osd_schedule_callback\n"); + return -1; + } + + cb->callback = func; + cb->data = data; + INIT_WORK(&cb->work, osd_callback_work); + return queue_work(wq, &cb->work); +} + |