diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-04-04 21:41:20 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-04-04 21:41:20 -0700 |
commit | 4dd2b32f3c48112da2ffe55279aedc10c3784f90 (patch) | |
tree | bcf9cd8019f030cb825bea7fceaed77ccc974a4f /drivers/staging/memrar/memrar_handler.c | |
parent | 00838d4f507ae73f2b5a260c826f6275bd2d4ba7 (diff) | |
download | linux-stable-4dd2b32f3c48112da2ffe55279aedc10c3784f90.tar.gz linux-stable-4dd2b32f3c48112da2ffe55279aedc10c3784f90.tar.bz2 linux-stable-4dd2b32f3c48112da2ffe55279aedc10c3784f90.zip |
staging: memrar: remove driver from tree
It's no longer needed at all.
Cc: Ossama Othman <ossama.othman@intel.com>
Cc: Eugene Epshteyn <eugene.epshteyn@intel.com>
Cc: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/memrar/memrar_handler.c')
-rw-r--r-- | drivers/staging/memrar/memrar_handler.c | 1007 |
1 files changed, 0 insertions, 1007 deletions
diff --git a/drivers/staging/memrar/memrar_handler.c b/drivers/staging/memrar/memrar_handler.c deleted file mode 100644 index cfcaa8e5b8e6..000000000000 --- a/drivers/staging/memrar/memrar_handler.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* - * memrar_handler 1.0: An Intel restricted access region handler device - * - * Copyright (C) 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General - * Public License as published by the Free Software Foundation. - * - * This program is distributed in the hope that 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. - * The full GNU General Public License is included in this - * distribution in the file called COPYING. - * - * ------------------------------------------------------------------- - * - * Moorestown restricted access regions (RAR) provide isolated - * areas of main memory that are only acceessible by authorized - * devices. - * - * The Intel Moorestown RAR handler module exposes a kernel space - * RAR memory management mechanism. It is essentially a - * RAR-specific allocator. - * - * Besides providing RAR buffer management, the RAR handler also - * behaves in many ways like an OS virtual memory manager. For - * example, the RAR "handles" created by the RAR handler are - * analogous to user space virtual addresses. - * - * RAR memory itself is never accessed directly by the RAR - * handler. - */ - -#include <linux/miscdevice.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/kref.h> -#include <linux/mutex.h> -#include <linux/kernel.h> -#include <linux/uaccess.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/io.h> -#include <linux/rar_register.h> - -#include "memrar.h" -#include "memrar_allocator.h" - - -#define MEMRAR_VER "1.0" - -/* - * Moorestown supports three restricted access regions. - * - * We only care about the first two, video and audio. The third, - * reserved for Chaabi and the P-unit, will be handled by their - * respective drivers. - */ -#define MRST_NUM_RAR 2 - -/* ---------------- -------------------- ------------------- */ - -/** - * struct memrar_buffer_info - struct that keeps track of all RAR buffers - * @list: Linked list of memrar_buffer_info objects. - * @buffer: Core RAR buffer information. - * @refcount: Reference count. - * @owner: File handle corresponding to process that reserved the - * block of memory in RAR. This will be zero for buffers - * allocated by other drivers instead of by a user space - * process. - * - * This structure encapsulates a link list of RAR buffers, as well as - * other characteristics specific to a given list node, such as the - * reference count on the corresponding RAR buffer. - */ -struct memrar_buffer_info { - struct list_head list; - struct RAR_buffer buffer; - struct kref refcount; - struct file *owner; -}; - -/** - * struct memrar_rar_info - characteristics of a given RAR - * @base: Base bus address of the RAR. - * @length: Length of the RAR. - * @iobase: Virtual address of RAR mapped into kernel. - * @allocator: Allocator associated with the RAR. Note the allocator - * "capacity" may be smaller than the RAR length if the - * length is not a multiple of the configured allocator - * block size. - * @buffers: Table that keeps track of all reserved RAR buffers. - * @lock: Lock used to synchronize access to RAR-specific data - * structures. - * - * Each RAR has an associated memrar_rar_info structure that describes - * where in memory the RAR is located, how large it is, and a list of - * reserved RAR buffers inside that RAR. Each RAR also has a mutex - * associated with it to reduce lock contention when operations on - * multiple RARs are performed in parallel. - */ -struct memrar_rar_info { - dma_addr_t base; - unsigned long length; - void __iomem *iobase; - struct memrar_allocator *allocator; - struct memrar_buffer_info buffers; - struct mutex lock; - int allocated; /* True if we own this RAR */ -}; - -/* - * Array of RAR characteristics. - */ -static struct memrar_rar_info memrars[MRST_NUM_RAR]; - -/* ---------------- -------------------- ------------------- */ - -/* Validate RAR type. */ -static inline int memrar_is_valid_rar_type(u32 type) -{ - return type == RAR_TYPE_VIDEO || type == RAR_TYPE_AUDIO; -} - -/* Check if an address/handle falls with the given RAR memory range. */ -static inline int memrar_handle_in_range(struct memrar_rar_info *rar, - u32 vaddr) -{ - unsigned long const iobase = (unsigned long) (rar->iobase); - return (vaddr >= iobase && vaddr < iobase + rar->length); -} - -/* Retrieve RAR information associated with the given handle. */ -static struct memrar_rar_info *memrar_get_rar_info(u32 vaddr) -{ - int i; - for (i = 0; i < MRST_NUM_RAR; ++i) { - struct memrar_rar_info * const rar = &memrars[i]; - if (memrar_handle_in_range(rar, vaddr)) - return rar; - } - - return NULL; -} - -/** - * memrar_get_bus address - handle to bus address - * - * Retrieve bus address from given handle. - * - * Returns address corresponding to given handle. Zero if handle is - * invalid. - */ -static dma_addr_t memrar_get_bus_address( - struct memrar_rar_info *rar, - u32 vaddr) -{ - unsigned long const iobase = (unsigned long) (rar->iobase); - - if (!memrar_handle_in_range(rar, vaddr)) - return 0; - - /* - * An assumption is made that the virtual address offset is - * the same as the bus address offset, at least based on the - * way this driver is implemented. For example, vaddr + 2 == - * baddr + 2. - * - * @todo Is that a valid assumption? - */ - return rar->base + (vaddr - iobase); -} - -/** - * memrar_get_physical_address - handle to physical address - * - * Retrieve physical address from given handle. - * - * Returns address corresponding to given handle. Zero if handle is - * invalid. - */ -static dma_addr_t memrar_get_physical_address( - struct memrar_rar_info *rar, - u32 vaddr) -{ - /* - * @todo This assumes that the bus address and physical - * address are the same. That is true for Moorestown - * but not necessarily on other platforms. This - * deficiency should be addressed at some point. - */ - return memrar_get_bus_address(rar, vaddr); -} - -/** - * memrar_release_block - release a block to the pool - * @kref: kref of block - * - * Core block release code. A node has hit zero references so can - * be released and the lists must be updated. - * - * Note: This code removes the node from a list. Make sure any list - * iteration is performed using list_for_each_safe(). - */ -static void memrar_release_block_i(struct kref *ref) -{ - /* - * Last reference is being released. Remove from the table, - * and reclaim resources. - */ - - struct memrar_buffer_info * const node = - container_of(ref, struct memrar_buffer_info, refcount); - - struct RAR_block_info * const user_info = - &node->buffer.info; - - struct memrar_allocator * const allocator = - memrars[user_info->type].allocator; - - list_del(&node->list); - - memrar_allocator_free(allocator, user_info->handle); - - kfree(node); -} - -/** - * memrar_init_rar_resources - configure a RAR - * @rarnum: rar that has been allocated - * @devname: name of our device - * - * Initialize RAR parameters, such as bus addresses, etc and make - * the resource accessible. - */ -static int memrar_init_rar_resources(int rarnum, char const *devname) -{ - /* ---- Sanity Checks ---- - * 1. RAR bus addresses in both Lincroft and Langwell RAR - * registers should be the same. - * a. There's no way we can do this through IA. - * - * 2. Secure device ID in Langwell RAR registers should be set - * appropriately, e.g. only LPE DMA for the audio RAR, and - * security for the other Langwell based RAR registers. - * a. There's no way we can do this through IA. - * - * 3. Audio and video RAR registers and RAR access should be - * locked down. If not, enable RAR access control. Except - * for debugging purposes, there is no reason for them to - * be unlocked. - * a. We can only do this for the Lincroft (IA) side. - * - * @todo Should the RAR handler driver even be aware of audio - * and video RAR settings? - */ - - /* - * RAR buffer block size. - * - * We choose it to be the size of a page to simplify the - * /dev/memrar mmap() implementation and usage. Otherwise - * paging is not involved once an RAR is locked down. - */ - static size_t const RAR_BLOCK_SIZE = PAGE_SIZE; - - dma_addr_t low, high; - struct memrar_rar_info * const rar = &memrars[rarnum]; - - BUG_ON(MRST_NUM_RAR != ARRAY_SIZE(memrars)); - BUG_ON(!memrar_is_valid_rar_type(rarnum)); - BUG_ON(rar->allocated); - - if (rar_get_address(rarnum, &low, &high) != 0) - /* No RAR is available. */ - return -ENODEV; - - if (low == 0 || high == 0) { - rar->base = 0; - rar->length = 0; - rar->iobase = NULL; - rar->allocator = NULL; - return -ENOSPC; - } - - /* - * @todo Verify that LNC and LNW RAR register contents - * addresses, security, etc are compatible and - * consistent). - */ - - rar->length = high - low + 1; - - /* Claim RAR memory as our own. */ - if (request_mem_region(low, rar->length, devname) == NULL) { - rar->length = 0; - pr_err("%s: Unable to claim RAR[%d] memory.\n", - devname, rarnum); - pr_err("%s: RAR[%d] disabled.\n", devname, rarnum); - return -EBUSY; - } - - rar->base = low; - - /* - * Now map it into the kernel address space. - * - * Note that the RAR memory may only be accessed by IA - * when debugging. Otherwise attempts to access the - * RAR memory when it is locked down will result in - * behavior similar to writing to /dev/null and - * reading from /dev/zero. This behavior is enforced - * by the hardware. Even if we don't access the - * memory, mapping it into the kernel provides us with - * a convenient RAR handle to bus address mapping. - */ - rar->iobase = ioremap_nocache(rar->base, rar->length); - if (rar->iobase == NULL) { - pr_err("%s: Unable to map RAR memory.\n", devname); - release_mem_region(low, rar->length); - return -ENOMEM; - } - - /* Initialize corresponding memory allocator. */ - rar->allocator = memrar_create_allocator((unsigned long) rar->iobase, - rar->length, RAR_BLOCK_SIZE); - if (rar->allocator == NULL) { - iounmap(rar->iobase); - release_mem_region(low, rar->length); - return -ENOMEM; - } - - pr_info("%s: BRAR[%d] bus address range = [0x%lx, 0x%lx]\n", - devname, rarnum, (unsigned long) low, (unsigned long) high); - - pr_info("%s: BRAR[%d] size = %zu KiB\n", - devname, rarnum, rar->allocator->capacity / 1024); - - rar->allocated = 1; - return 0; -} - -/** - * memrar_fini_rar_resources - free up RAR resources - * - * Finalize RAR resources. Free up the resource tables, hand the memory - * back to the kernel, unmap the device and release the address space. - */ -static void memrar_fini_rar_resources(void) -{ - int z; - struct memrar_buffer_info *pos; - struct memrar_buffer_info *tmp; - - /* - * @todo Do we need to hold a lock at this point in time? - * (module initialization failure or exit?) - */ - - for (z = MRST_NUM_RAR; z-- != 0; ) { - struct memrar_rar_info * const rar = &memrars[z]; - - if (!rar->allocated) - continue; - - /* Clean up remaining resources. */ - - list_for_each_entry_safe(pos, - tmp, - &rar->buffers.list, - list) { - kref_put(&pos->refcount, memrar_release_block_i); - } - - memrar_destroy_allocator(rar->allocator); - rar->allocator = NULL; - - iounmap(rar->iobase); - release_mem_region(rar->base, rar->length); - - rar->iobase = NULL; - rar->base = 0; - rar->length = 0; - - unregister_rar(z); - } -} - -/** - * memrar_reserve_block - handle an allocation request - * @request: block being requested - * @filp: owner it is tied to - * - * Allocate a block of the requested RAR. If successful return the - * request object filled in and zero, if not report an error code - */ - -static long memrar_reserve_block(struct RAR_buffer *request, - struct file *filp) -{ - struct RAR_block_info * const rinfo = &request->info; - struct RAR_buffer *buffer; - struct memrar_buffer_info *buffer_info; - u32 handle; - struct memrar_rar_info *rar = NULL; - - /* Prevent array overflow. */ - if (!memrar_is_valid_rar_type(rinfo->type)) - return -EINVAL; - - rar = &memrars[rinfo->type]; - if (!rar->allocated) - return -ENODEV; - - /* Reserve memory in RAR. */ - handle = memrar_allocator_alloc(rar->allocator, rinfo->size); - if (handle == 0) - return -ENOMEM; - - buffer_info = kmalloc(sizeof(*buffer_info), GFP_KERNEL); - - if (buffer_info == NULL) { - memrar_allocator_free(rar->allocator, handle); - return -ENOMEM; - } - - buffer = &buffer_info->buffer; - buffer->info.type = rinfo->type; - buffer->info.size = rinfo->size; - - /* Memory handle corresponding to the bus address. */ - buffer->info.handle = handle; - buffer->bus_address = memrar_get_bus_address(rar, handle); - - /* - * Keep track of owner so that we can later cleanup if - * necessary. - */ - buffer_info->owner = filp; - - kref_init(&buffer_info->refcount); - - mutex_lock(&rar->lock); - list_add(&buffer_info->list, &rar->buffers.list); - mutex_unlock(&rar->lock); - - rinfo->handle = buffer->info.handle; - request->bus_address = buffer->bus_address; - - return 0; -} - -/** - * memrar_release_block - release a RAR block - * @addr: address in RAR space - * - * Release a previously allocated block. Releases act on complete - * blocks, partially freeing a block is not supported - */ - -static long memrar_release_block(u32 addr) -{ - struct memrar_buffer_info *pos; - struct memrar_buffer_info *tmp; - struct memrar_rar_info * const rar = memrar_get_rar_info(addr); - long result = -EINVAL; - - if (rar == NULL) - return -ENOENT; - - mutex_lock(&rar->lock); - - /* - * Iterate through the buffer list to find the corresponding - * buffer to be released. - */ - list_for_each_entry_safe(pos, - tmp, - &rar->buffers.list, - list) { - struct RAR_block_info * const info = - &pos->buffer.info; - - /* - * Take into account handle offsets that may have been - * added to the base handle, such as in the following - * scenario: - * - * u32 handle = base + offset; - * rar_handle_to_bus(handle); - * rar_release(handle); - */ - if (addr >= info->handle - && addr < (info->handle + info->size) - && memrar_is_valid_rar_type(info->type)) { - kref_put(&pos->refcount, memrar_release_block_i); - result = 0; - break; - } - } - - mutex_unlock(&rar->lock); - - return result; -} - -/** - * memrar_get_stats - read statistics for a RAR - * @r: statistics to be filled in - * - * Returns the statistics data for the RAR, or an error code if - * the request cannot be completed - */ -static long memrar_get_stat(struct RAR_stat *r) -{ - struct memrar_allocator *allocator; - - if (!memrar_is_valid_rar_type(r->type)) - return -EINVAL; - - if (!memrars[r->type].allocated) - return -ENODEV; - - allocator = memrars[r->type].allocator; - - BUG_ON(allocator == NULL); - - /* - * Allocator capacity doesn't change over time. No - * need to synchronize. - */ - r->capacity = allocator->capacity; - - mutex_lock(&allocator->lock); - r->largest_block_size = allocator->largest_free_area; - mutex_unlock(&allocator->lock); - return 0; -} - -/** - * memrar_ioctl - ioctl callback - * @filp: file issuing the request - * @cmd: command - * @arg: pointer to control information - * - * Perform one of the ioctls supported by the memrar device - */ - -static long memrar_ioctl(struct file *filp, - unsigned int cmd, - unsigned long arg) -{ - void __user *argp = (void __user *)arg; - long result = 0; - - struct RAR_buffer buffer; - struct RAR_block_info * const request = &buffer.info; - struct RAR_stat rar_info; - u32 rar_handle; - - switch (cmd) { - case RAR_HANDLER_RESERVE: - if (copy_from_user(request, - argp, - sizeof(*request))) - return -EFAULT; - - result = memrar_reserve_block(&buffer, filp); - if (result != 0) - return result; - - return copy_to_user(argp, request, sizeof(*request)); - - case RAR_HANDLER_RELEASE: - if (copy_from_user(&rar_handle, - argp, - sizeof(rar_handle))) - return -EFAULT; - - return memrar_release_block(rar_handle); - - case RAR_HANDLER_STAT: - if (copy_from_user(&rar_info, - argp, - sizeof(rar_info))) - return -EFAULT; - - /* - * Populate the RAR_stat structure based on the RAR - * type given by the user - */ - if (memrar_get_stat(&rar_info) != 0) - return -EINVAL; - - /* - * @todo Do we need to verify destination pointer - * "argp" is non-zero? Is that already done by - * copy_to_user()? - */ - return copy_to_user(argp, - &rar_info, - sizeof(rar_info)) ? -EFAULT : 0; - - default: - return -ENOTTY; - } - - return 0; -} - -/** - * memrar_mmap - mmap helper for deubgging - * @filp: handle doing the mapping - * @vma: memory area - * - * Support the mmap operation on the RAR space for debugging systems - * when the memory is not locked down. - */ - -static int memrar_mmap(struct file *filp, struct vm_area_struct *vma) -{ - /* - * This mmap() implementation is predominantly useful for - * debugging since the CPU will be prevented from accessing - * RAR memory by the hardware when RAR is properly locked - * down. - * - * In order for this implementation to be useful RAR memory - * must be not be locked down. However, we only want to do - * that when debugging. DO NOT leave RAR memory unlocked in a - * deployed device that utilizes RAR. - */ - - size_t const size = vma->vm_end - vma->vm_start; - - /* Users pass the RAR handle as the mmap() offset parameter. */ - unsigned long const handle = vma->vm_pgoff << PAGE_SHIFT; - - struct memrar_rar_info * const rar = memrar_get_rar_info(handle); - unsigned long pfn; - - /* Only allow priviledged apps to go poking around this way */ - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - - /* Invalid RAR handle or size passed to mmap(). */ - if (rar == NULL - || handle == 0 - || size > (handle - (unsigned long) rar->iobase)) - return -EINVAL; - - /* - * Retrieve physical address corresponding to the RAR handle, - * and convert it to a page frame. - */ - pfn = memrar_get_physical_address(rar, handle) >> PAGE_SHIFT; - - - pr_debug("memrar: mapping RAR range [0x%lx, 0x%lx) into user space.\n", - handle, - handle + size); - - /* - * Map RAR memory into user space. This is really only useful - * for debugging purposes since the memory won't be - * accessible, i.e. reads return zero and writes are ignored, - * when RAR access control is enabled. - */ - if (remap_pfn_range(vma, - vma->vm_start, - pfn, - size, - vma->vm_page_prot)) - return -EAGAIN; - - /* vma->vm_ops = &memrar_mem_ops; */ - - return 0; -} - -/** - * memrar_open - device open method - * @inode: inode to open - * @filp: file handle - * - * As we support multiple arbitary opens there is no work to be done - * really. - */ - -static int memrar_open(struct inode *inode, struct file *filp) -{ - nonseekable_open(inode, filp); - return 0; -} - -/** - * memrar_release - close method for miscev - * @inode: inode of device - * @filp: handle that is going away - * - * Free up all the regions that belong to this file handle. We use - * the handle as a natural Linux style 'lifetime' indicator and to - * ensure resources are not leaked when their owner explodes in an - * unplanned fashion. - */ - -static int memrar_release(struct inode *inode, struct file *filp) -{ - /* Free all regions associated with the given file handle. */ - - struct memrar_buffer_info *pos; - struct memrar_buffer_info *tmp; - int z; - - for (z = 0; z != MRST_NUM_RAR; ++z) { - struct memrar_rar_info * const rar = &memrars[z]; - - mutex_lock(&rar->lock); - - list_for_each_entry_safe(pos, - tmp, - &rar->buffers.list, - list) { - if (filp == pos->owner) - kref_put(&pos->refcount, - memrar_release_block_i); - } - - mutex_unlock(&rar->lock); - } - - return 0; -} - -/** - * rar_reserve - reserve RAR memory - * @buffers: buffers to reserve - * @count: number wanted - * - * Reserve a series of buffers in the RAR space. Returns the number of - * buffers successfully allocated - */ - -size_t rar_reserve(struct RAR_buffer *buffers, size_t count) -{ - struct RAR_buffer * const end = - (buffers == NULL ? buffers : buffers + count); - struct RAR_buffer *i; - - size_t reserve_count = 0; - - for (i = buffers; i != end; ++i) { - if (memrar_reserve_block(i, NULL) == 0) - ++reserve_count; - else - i->bus_address = 0; - } - - return reserve_count; -} -EXPORT_SYMBOL(rar_reserve); - -/** - * rar_release - return RAR buffers - * @buffers: buffers to release - * @size: size of released block - * - * Return a set of buffers to the RAR pool - */ - -size_t rar_release(struct RAR_buffer *buffers, size_t count) -{ - struct RAR_buffer * const end = - (buffers == NULL ? buffers : buffers + count); - struct RAR_buffer *i; - - size_t release_count = 0; - - for (i = buffers; i != end; ++i) { - u32 * const handle = &i->info.handle; - if (memrar_release_block(*handle) == 0) { - /* - * @todo We assume we should do this each time - * the ref count is decremented. Should - * we instead only do this when the ref - * count has dropped to zero, and the - * buffer has been completely - * released/unmapped? - */ - *handle = 0; - ++release_count; - } - } - - return release_count; -} -EXPORT_SYMBOL(rar_release); - -/** - * rar_handle_to_bus - RAR to bus address - * @buffers: RAR buffer structure - * @count: number of buffers to convert - * - * Turn a list of RAR handle mappings into actual bus addresses. Note - * that when the device is locked down the bus addresses in question - * are not CPU accessible. - */ - -size_t rar_handle_to_bus(struct RAR_buffer *buffers, size_t count) -{ - struct RAR_buffer * const end = - (buffers == NULL ? buffers : buffers + count); - struct RAR_buffer *i; - struct memrar_buffer_info *pos; - - size_t conversion_count = 0; - - /* - * Find all bus addresses corresponding to the given handles. - * - * @todo Not liking this nested loop. Optimize. - */ - for (i = buffers; i != end; ++i) { - struct memrar_rar_info * const rar = - memrar_get_rar_info(i->info.handle); - - /* - * Check if we have a bogus handle, and then continue - * with remaining buffers. - */ - if (rar == NULL) { - i->bus_address = 0; - continue; - } - - mutex_lock(&rar->lock); - - list_for_each_entry(pos, &rar->buffers.list, list) { - struct RAR_block_info * const user_info = - &pos->buffer.info; - - /* - * Take into account handle offsets that may - * have been added to the base handle, such as - * in the following scenario: - * - * u32 handle = base + offset; - * rar_handle_to_bus(handle); - */ - - if (i->info.handle >= user_info->handle - && i->info.handle < (user_info->handle - + user_info->size)) { - u32 const offset = - i->info.handle - user_info->handle; - - i->info.type = user_info->type; - i->info.size = user_info->size - offset; - i->bus_address = - pos->buffer.bus_address - + offset; - - /* Increment the reference count. */ - kref_get(&pos->refcount); - - ++conversion_count; - break; - } else { - i->bus_address = 0; - } - } - - mutex_unlock(&rar->lock); - } - - return conversion_count; -} -EXPORT_SYMBOL(rar_handle_to_bus); - -static const struct file_operations memrar_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = memrar_ioctl, - .mmap = memrar_mmap, - .open = memrar_open, - .release = memrar_release, - .llseek = no_llseek, -}; - -static struct miscdevice memrar_miscdev = { - .minor = MISC_DYNAMIC_MINOR, /* dynamic allocation */ - .name = "memrar", /* /dev/memrar */ - .fops = &memrar_fops -}; - -static char const banner[] __initdata = - KERN_INFO - "Intel RAR Handler: " MEMRAR_VER " initialized.\n"; - -/** - * memrar_registration_callback - RAR obtained - * @rar: RAR number - * - * We have been granted ownership of the RAR. Add it to our memory - * management tables - */ - -static int memrar_registration_callback(unsigned long rar) -{ - /* - * We initialize the RAR parameters early on so that we can - * discontinue memrar device initialization and registration - * if suitably configured RARs are not available. - */ - return memrar_init_rar_resources(rar, memrar_miscdev.name); -} - -/** - * memrar_init - initialise RAR support - * - * Initialise support for RAR handlers. This may get loaded before - * the RAR support is activated, but the callbacks on the registration - * will handle that situation for us anyway. - */ - -static int __init memrar_init(void) -{ - int err; - int i; - - printk(banner); - - /* - * Some delayed initialization is performed in this driver. - * Make sure resources that are used during driver clean-up - * (e.g. during driver's release() function) are fully - * initialized before first use. This is particularly - * important for the case when the delayed initialization - * isn't completed, leaving behind a partially initialized - * driver. - * - * Such a scenario can occur when RAR is not available on the - * platform, and the driver is release()d. - */ - for (i = 0; i != ARRAY_SIZE(memrars); ++i) { - struct memrar_rar_info * const rar = &memrars[i]; - mutex_init(&rar->lock); - INIT_LIST_HEAD(&rar->buffers.list); - } - - err = misc_register(&memrar_miscdev); - if (err) - return err; - - /* Now claim the two RARs we want */ - err = register_rar(0, memrar_registration_callback, 0); - if (err) - goto fail; - - err = register_rar(1, memrar_registration_callback, 1); - if (err == 0) - return 0; - - /* It is possible rar 0 registered and allocated resources then rar 1 - failed so do a full resource free */ - memrar_fini_rar_resources(); -fail: - misc_deregister(&memrar_miscdev); - return err; -} - -/** - * memrar_exit - unregister and unload - * - * Unregister the device and then unload any mappings and release - * the RAR resources - */ - -static void __exit memrar_exit(void) -{ - misc_deregister(&memrar_miscdev); - memrar_fini_rar_resources(); -} - - -module_init(memrar_init); -module_exit(memrar_exit); - - -MODULE_AUTHOR("Ossama Othman <ossama.othman@intel.com>"); -MODULE_DESCRIPTION("Intel Restricted Access Region Handler"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(MEMRAR_VER); - - - -/* - Local Variables: - c-file-style: "linux" - End: -*/ |