patch-2.4.22 linux-2.4.22/arch/ia64/sn/io/pciba.c

Next file: linux-2.4.22/arch/ia64/sn/io/pciio.c
Previous file: linux-2.4.22/arch/ia64/sn/io/pci_dma.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/arch/ia64/sn/io/pciba.c linux-2.4.22/arch/ia64/sn/io/pciba.c
@@ -1,916 +0,0 @@
-/*
- * arch/ia64/sn/io/pciba.c
- *
- * IRIX PCIBA-inspired user mode PCI interface
- *
- * requires: devfs
- *
- * device nodes show up in /dev/pci/BB/SS.F (where BB is the bus the
- * device is on, SS is the slot the device is in, and F is the
- * device's function on a multi-function card).
- *
- * when compiled into the kernel, it will only be initialized by the
- * sgi sn1 specific initialization code.  in this case, device nodes
- * are under /dev/hw/..../
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License.  See the file "COPYING" in the main directory of
- * this archive for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
- *
- * 03262001 - Initial version by Chad Talbott
- */
-
-
-/* jesse's beefs:
-
-   register_pci_device should be documented
-   
-   grossness with do_swap should be documented
-   
-   big, gross union'ized node_data should be replaced with independent
-   structures
-
-   replace global list of nodes with global lists of resources.  could
-   use object oriented approach of allocating and cleaning up
-   resources.
-   
-*/
-
-
-#include <linux/config.h>
-#ifndef CONFIG_DEVFS_FS
-#  error PCIBA requires devfs
-#endif
-
-#include <linux/module.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/pci.h>
-#include <linux/list.h>
-
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/mman.h>
-#include <linux/init.h>
-#include <linux/raw.h>
-#include <linux/capability.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/pgalloc.h>
-#include <asm/page.h>
-
-#include <asm/sn/pci/pciba.h>
-
-
-MODULE_DESCRIPTION("User mode PCI interface");
-MODULE_AUTHOR("Chad Talbott");
-
-
-#undef DEBUG_PCIBA
-/* #define DEBUG_PCIBA */
-
-#undef TRACE_PCIBA
-/* #define TRACE_PCIBA */
-
-#if defined(DEBUG_PCIBA)
-#  define DPRINTF(x...) printk(KERN_DEBUG x)
-#else
-#  define DPRINTF(x...)
-#endif
-
-#if defined(TRACE_PCIBA)
-#  if defined(__GNUC__)
-#    define TRACE()	printk(KERN_DEBUG "%s:%d:%s\n", \
-			       __FILE__, __LINE__, __FUNCTION__)
-#  else
-#    define TRACE()	printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
-#  endif
-#else
-#  define TRACE()
-#endif
-
-
-typedef enum { failure, success } status;
-typedef enum { false, true } boolean;
-
-
-/* major data structures:
-
-   struct node_data -
-   
-   	one for each file registered with devfs.  contains everything
-   	that any file's fops would need to know about.
-
-   struct dma_allocation -
-
-   	a single DMA allocation.  only the 'dma' nodes care about
-   	these.  they are there primarily to allow the driver to look
-   	up the kernel virtual address of dma buffers allocated by
-   	pci_alloc_consistent, as the application is only given the
-   	physical address (to program the device's dma, presumably) and
-   	cannot supply the kernel virtual address when freeing the
-   	buffer.
-
-	it's also useful to maintain a list of buffers allocated
-	through a specific node to allow some sanity checking by this
-	driver.  this prevents (for example) a broken application from
-	freeing buffers that it didn't allocate, or buffers allocated
-	on another node.
-   
-   global_node_list -
-
-   	a list of all nodes allocated.  this allows the driver to free
-   	all the memory it has 'kmalloc'd in case of an error, or on
-   	module removal.
-
-   global_dma_list -
-
-        a list of all dma buffers allocated by this driver.  this
-	allows the driver to 'pci_free_consistent' all buffers on
-	module removal or error.
-
-*/
-
-
-struct node_data {
-	/* flat list of all the device nodes.  makes it easy to free
-	   them all when we're unregistered */
-	struct list_head global_node_list;
-	devfs_handle_t devfs_handle;
-
-	void (* cleanup)(struct node_data *);
-
-	union {
-		struct {
-			struct pci_dev * dev;
-			struct list_head dma_allocs;
-			boolean mmapped;
-		} dma;
-		struct {
-			struct pci_dev * dev;
-			u32 saved_rom_base_reg;
-			boolean mmapped;
-		} rom;
-		struct {
-			struct resource * res;
-		} base;
-		struct {
-			struct pci_dev * dev;
-		} config;
-	} u;
-};
-
-struct dma_allocation {
-	struct list_head list;
-
-	dma_addr_t handle;
-	void * va;
-	size_t size;
-};
-
-
-static LIST_HEAD(global_node_list);
-static LIST_HEAD(global_dma_list);
-
-
-/* module entry points */
-int __init pciba_init(void);
-void __exit pciba_exit(void);
-
-static status __init register_with_devfs(void);
-static void __exit unregister_with_devfs(void);
-
-static status __init register_pci_device(devfs_handle_t device_dir_handle,
-					 struct pci_dev * dev);
-
-/* file operations */
-static int generic_open(struct inode * inode, struct file * file);
-static int rom_mmap(struct file * file, struct vm_area_struct * vma);
-static int rom_release(struct inode * inode, struct file * file);
-static int base_mmap(struct file * file, struct vm_area_struct * vma);
-static int config_ioctl(struct inode * inode, struct file * file, 
-			unsigned int cmd, 
-			unsigned long arg);
-static int dma_ioctl(struct inode * inode, struct file * file, 
-		     unsigned int cmd, 
-		     unsigned long arg);
-static int dma_mmap(struct file * file, struct vm_area_struct * vma);
-
-/* support routines */
-static int mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va);
-static int mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va);
-
-#ifdef DEBUG_PCIBA
-static void dump_nodes(struct list_head * nodes);
-static void dump_allocations(struct list_head * dalp);
-#endif
-
-/* file operations for each type of node */
-static struct file_operations rom_fops = {
-	owner:		THIS_MODULE,
-	mmap:		rom_mmap,
-	open:		generic_open,
-	release:	rom_release
-};
- 
-
-static struct file_operations base_fops = {
-	owner:		THIS_MODULE,
-	mmap:		base_mmap,
-	open:		generic_open
-};
-
-
-static struct file_operations config_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		config_ioctl,
-	open:		generic_open
-};	
-
-static struct file_operations dma_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		dma_ioctl,
-	mmap:		dma_mmap,
-	open:		generic_open
-};	
-
-
-module_init(pciba_init);
-module_exit(pciba_exit);
-
-
-int __init
-pciba_init(void)
-{
-	TRACE();
-
-	if (register_with_devfs() == failure)
-		return 1; /* failure */
-
-	printk("PCIBA (a user mode PCI interface) initialized.\n");
-
-	return 0; /* success */
-}
-
-
-void __exit
-pciba_exit(void)
-{
-	TRACE();
-
-	/* FIXME: should also free all that memory that we allocated
-           ;) */
-	unregister_with_devfs();
-}
-
-
-# if 0
-static void __exit
-free_nodes(void)
-{
-	struct node_data * nd;
-	
-	TRACE();
-
-	list_for_each(nd, &node_list) {
-		kfree(list_entry(nd, struct nd, node_list));
-	}
-}
-#endif
-
-
-static devfs_handle_t pciba_devfs_handle;
-
-
-extern devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-static status __init
-register_with_devfs(void)
-{
-	struct pci_dev * dev;
-	devfs_handle_t device_dir_handle;
-
-	TRACE();
-
-	/* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */
-
-	pci_for_each_dev(dev) {
-		device_dir_handle = devfn_to_vertex(dev->bus->number,
-						    dev->devfn);
-		if (device_dir_handle == NULL)
-			return failure;
-	
-		if (register_pci_device(device_dir_handle, dev) == failure) {
-			devfs_unregister(pciba_devfs_handle);
-			return failure;
-		}
-	}
-
-	return success;
-}
-
-static void __exit
-unregister_with_devfs(void)
-{
-	struct list_head * lhp;
-	struct node_data * nd;
-	
-	TRACE();
-
-	list_for_each(lhp, &global_node_list) {
-		nd = list_entry(lhp, struct node_data, global_node_list);
-		devfs_unregister(nd->devfs_handle);
-	}
-
-}
-
-
-struct node_data * new_node(void)
-{
-	struct node_data * node;
-	
-	TRACE();
-	
-	node = kmalloc(sizeof(struct node_data), GFP_KERNEL);
-	if (node == NULL)
-		return NULL;
-	list_add(&node->global_node_list, &global_node_list);
-	return node;
-}
-
-
-void dma_cleanup(struct node_data * dma_node)
-{
-	TRACE();
-
-	/* FIXME: should free these allocations */
-#ifdef DEBUG_PCIBA
-	dump_allocations(&dma_node->u.dma.dma_allocs);
-#endif
-	devfs_unregister(dma_node->devfs_handle);
-}
-
-
-void init_dma_node(struct node_data * node,
-		   struct pci_dev * dev, devfs_handle_t dh)
-{
-	TRACE();
-
-	node->devfs_handle = dh;
-	node->u.dma.dev = dev;
-	node->cleanup = dma_cleanup;
-	INIT_LIST_HEAD(&node->u.dma.dma_allocs);
-}
-
-
-void rom_cleanup(struct node_data * rom_node)
-{
-	TRACE();
-
-	if (rom_node->u.rom.mmapped)
-		pci_write_config_dword(rom_node->u.rom.dev,
-				       PCI_ROM_ADDRESS,
-				       rom_node->u.rom.saved_rom_base_reg);
-	devfs_unregister(rom_node->devfs_handle);
-}
-
-
-void init_rom_node(struct node_data * node,
-		   struct pci_dev * dev, devfs_handle_t dh)
-{
-	TRACE();
-
-	node->devfs_handle = dh;
-	node->u.rom.dev = dev;
-	node->cleanup = rom_cleanup;
-	node->u.rom.mmapped = false;
-}
-
-
-static status __init
-register_pci_device(devfs_handle_t device_dir_handle, struct pci_dev * dev)
-{
-	struct node_data * nd;
-	char devfs_path[20];
-	devfs_handle_t node_devfs_handle;
-	int ri;
-
-	TRACE();
-
-
-	/* register nodes for all the device's base address registers */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (pci_resource_len(dev, ri) != 0) {
-			sprintf(devfs_path, "base/%d", ri);
-			if (devfs_register(device_dir_handle, devfs_path,
-					   DEVFS_FL_NONE,
-					   0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-		}
-	}
-	
-	/* register a node corresponding to the first MEM resource on
-           the device */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (dev->resource[ri].flags & IORESOURCE_MEM &&
-		    pci_resource_len(dev, ri) != 0) {
-			if (devfs_register(device_dir_handle, "mem",
-					   DEVFS_FL_NONE, 0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-			break;
-		}
-	}
-
-	/* also register a node corresponding to the first IO resource
-           on the device */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (dev->resource[ri].flags & IORESOURCE_IO &&
-		    pci_resource_len(dev, ri) != 0) {
-			if (devfs_register(device_dir_handle, "io",
-					   DEVFS_FL_NONE, 0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-			break;
-		}
-	}
-
-	/* register a node corresponding to the device's ROM resource,
-           if present */
-	if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) {
-		nd = new_node();
-		if (nd == NULL)
-			return failure;
-		node_devfs_handle = devfs_register(device_dir_handle, "rom",
-						   DEVFS_FL_NONE, 0, 0,
-						   S_IFREG | S_IRUSR,
-						   &rom_fops, nd);
-		if (node_devfs_handle == NULL)
-			return failure;
-		init_rom_node(nd, dev, node_devfs_handle);
-	}
-
-	/* register a node that allows ioctl's to read and write to
-           the device's config space */
-	if (devfs_register(device_dir_handle, "config", DEVFS_FL_NONE,
-			   0, 0, S_IFREG | S_IRUSR | S_IWUSR,
-			   &config_fops, dev) == NULL)
-		return failure;
-
-
-	/* finally, register a node that allows ioctl's to allocate
-           and free DMA buffers, as well as memory map those
-           buffers. */
-	nd = new_node();
-	if (nd == NULL)
-		return failure;
-	node_devfs_handle =
-		devfs_register(device_dir_handle, "dma", DEVFS_FL_NONE,
-			       0, 0, S_IFREG | S_IRUSR | S_IWUSR,
-			       &dma_fops, nd);
-	if (node_devfs_handle == NULL)
-		return failure;
-	init_dma_node(nd, dev, node_devfs_handle);
-
-#ifdef DEBUG_PCIBA
-	dump_nodes(&global_node_list);
-#endif
-	
-	return success;
-}
-
-
-static int
-generic_open(struct inode * inode, struct file * file)
-{
-	TRACE();
-
-	/* FIXME: should check that they're not trying to open the ROM
-           writable */
-
-	return 0; /* success */
-}
-
-
-static int
-rom_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	unsigned long pci_pa;
-	struct node_data * nd;
-
-	TRACE();
-
-	nd = (struct node_data * )file->private_data;
-
-	pci_pa = pci_resource_start(nd->u.rom.dev, PCI_ROM_RESOURCE);
-
-	if (!nd->u.rom.mmapped) {
-		nd->u.rom.mmapped = true;
-		DPRINTF("Enabling ROM address decoder.\n");
-		DPRINTF(
-"rom_mmap: FIXME: some cards do not allow both ROM and memory addresses to\n"
-"rom_mmap: FIXME: be enabled simultaneously, as they share a decoder.\n");
-		pci_read_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				      &nd->u.rom.saved_rom_base_reg);
-		DPRINTF("ROM base address contains %x\n",
-			nd->u.rom.saved_rom_base_reg);
-		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				       nd->u.rom.saved_rom_base_reg |
-				       PCI_ROM_ADDRESS_ENABLE);
-	}
-	
-	return mmap_pci_address(vma, pci_pa);
-}
-
-
-static int
-rom_release(struct inode * inode, struct file * file)
-{
-	struct node_data * nd;
-
-	TRACE();
-
-	nd = (struct node_data * )file->private_data;
-
-	if (nd->u.rom.mmapped) {
-		nd->u.rom.mmapped = false;
-		DPRINTF("Disabling ROM address decoder.\n");
-		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				       nd->u.rom.saved_rom_base_reg);
-	}
-	return 0; /* indicate success */
-}
-
-
-static int
-base_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	struct resource * resource;
-
-	TRACE();
-
-	resource = (struct resource *)file->private_data;
-
-	return mmap_pci_address(vma, resource->start);
-}
-
-
-static int
-config_ioctl(struct inode * inode, struct file * file, 
-	     unsigned int cmd, 
-	     unsigned long arg)
-{
-	struct pci_dev * dev;
-
-	union cfg_data {
-		uint8_t byte;
-		uint16_t word;
-		uint32_t dword;
-	} read_data, write_data;
-
-	int dir, size, offset;
-
-	TRACE();
-
-	DPRINTF("cmd = %x (DIR = %x, TYPE = %x, NR = %x, SIZE = %x)\n", 
-		cmd, 
-		_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
-	DPRINTF("arg = %lx\n", arg);
-
-	dev = (struct pci_dev *)file->private_data;
-
-	/* PCIIOCCFG{RD,WR}: read and/or write PCI configuration
-	   space. If both, the read happens first (this becomes a swap
-	   operation, atomic with respect to other updates through
-	   this path).  */
-
-	dir = _IOC_DIR(cmd);
-
-#define do_swap(suffix, type)	 					\
-	do {								\
-		if (dir & _IOC_READ) {					\
-			pci_read_config_##suffix(dev, _IOC_NR(cmd), 	\
-						 &read_data.suffix);	\
-		}							\
-		if (dir & _IOC_WRITE) {					\
-			get_user(write_data.suffix, (type)arg);		\
-			pci_write_config_##suffix(dev, _IOC_NR(cmd), 	\
-						  write_data.suffix);	\
-		}							\
-		if (dir & _IOC_READ) {					\
-			put_user(read_data.suffix, (type)arg);		\
-		}							\
-	} while (0)
-
-	size = _IOC_SIZE(cmd);
-	offset = _IOC_NR(cmd);
-
-	DPRINTF("sanity check\n");
-	if (((size > 0) || (size <= 4)) &&
-	    ((offset + size) <= 256) &&
-	    (dir & (_IOC_READ | _IOC_WRITE))) {
-
-		switch (size)
-		{
-		case 1:
-			do_swap(byte, uint8_t *);
-			break;
-		case 2:
-			do_swap(word, uint16_t *);
-			break;
-		case 4:
-			do_swap(dword, uint32_t *);
-			break;
-		default:
-			DPRINTF("invalid ioctl\n");
-			return -EINVAL;
-		}
-	} else
-		return -EINVAL;
-		
-	return 0;
-}
-
-
-#ifdef DEBUG_PCIBA
-static void
-dump_allocations(struct list_head * dalp)
-{
-	struct dma_allocation * dap;
-	struct list_head * p;
-	
-	printk("{\n");
-	list_for_each(p, dalp) {
-		dap = list_entry(p, struct dma_allocation, 
-				 list);
-		printk("  handle = %lx, va = %p\n",
-		       dap->handle, dap->va);
-	}
-	printk("}\n");
-}
-
-static void
-dump_nodes(struct list_head * nodes)
-{
-	struct node_data * ndp;
-	struct list_head * p;
-	
-	printk("{\n");
-	list_for_each(p, nodes) {
-		ndp = list_entry(p, struct node_data, 
-				 global_node_list);
-		printk("  %p\n", (void *)ndp);
-	}
-	printk("}\n");
-}
-
-
-#if 0
-#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-
-static void
-test_list(void)
-{
-	u64 i;
-	LIST_HEAD(the_list);
-
-	for (i = 0; i < 5; i++) {
-		struct dma_allocation * new_alloc;
-		NEW(new_alloc);
-		new_alloc->va = (void *)i;
-		new_alloc->handle = 5*i;
-		printk("%d - the_list->next = %lx\n", i, the_list.next);
-		list_add(&new_alloc->list, &the_list);
-	}
-	dump_allocations(&the_list);
-}
-#endif
-#endif
-
-
-static LIST_HEAD(dma_buffer_list);
-
-
-static int
-dma_ioctl(struct inode * inode, struct file * file, 
-	  unsigned int cmd, 
-	  unsigned long arg)
-{
-	struct node_data * nd;
-	uint64_t argv;
-	int result;
-	struct dma_allocation * dma_alloc;
-	struct list_head * iterp;
-
-	TRACE();
-
-	DPRINTF("cmd = %x\n", cmd);
-	DPRINTF("arg = %lx\n", arg);
-
-	nd = (struct node_data *)file->private_data;
-
-#ifdef DEBUG_PCIBA
-	DPRINTF("at dma_ioctl entry\n");
-	dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-
-	switch (cmd) {
-	case PCIIOCDMAALLOC:
-		/* PCIIOCDMAALLOC: allocate a chunk of physical memory
-		   and set it up for DMA. Return the PCI address that
-		   gets to it.  */
-		DPRINTF("case PCIIOCDMAALLOC (%lx)\n", PCIIOCDMAALLOC);
-		
-		if ( (result = get_user(argv, (uint64_t *)arg)) )
-			return result;
-		DPRINTF("argv (size of buffer) = %lx\n", argv);
-
-		dma_alloc = (struct dma_allocation *)
-			kmalloc(sizeof(struct dma_allocation), GFP_KERNEL);
-		if (dma_alloc == NULL)
-			return -ENOMEM;
-
-		dma_alloc->size = (size_t)argv;
-		dma_alloc->va = pci_alloc_consistent(nd->u.dma.dev,
-						     dma_alloc->size,
-						     &dma_alloc->handle);
-		DPRINTF("dma_alloc->va = %p, dma_alloc->handle = %lx\n",
-			dma_alloc->va, dma_alloc->handle);
-		if (dma_alloc->va == NULL) {
-			kfree(dma_alloc);
-			return -ENOMEM;
-		}
-
-		list_add(&dma_alloc->list, &nd->u.dma.dma_allocs);
-		if ( (result = put_user((uint64_t)dma_alloc->handle, 
-				      (uint64_t *)arg)) ) {
-			DPRINTF("put_user failed\n");
-			pci_free_consistent(nd->u.dma.dev, (size_t)argv,
-					    dma_alloc->va, dma_alloc->handle);
-			kfree(dma_alloc);
-			return result;
-		}
-
-#ifdef DEBUG_PCIBA
-		DPRINTF("after insertion\n");
-		dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-		break;
-
-	case PCIIOCDMAFREE:
-		DPRINTF("case PCIIOCDMAFREE (%lx)\n", PCIIOCDMAFREE);
-
-		if ( (result = get_user(argv, (uint64_t *)arg)) ) {
-			DPRINTF("get_user failed\n");
-			return result;
-		}
-
-		DPRINTF("argv (physical address of DMA buffer) = %lx\n", argv);
-		list_for_each(iterp, &nd->u.dma.dma_allocs) {
-			struct dma_allocation * da =
-				list_entry(iterp, struct dma_allocation, list);
-			if (da->handle == argv) {
-				pci_free_consistent(nd->u.dma.dev, da->size,
-						    da->va, da->handle);
-				list_del(&da->list);
-				kfree(da);
-#ifdef DEBUG_PCIBA
-				DPRINTF("after deletion\n");
-				dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-				return 0; /* success */
-			}
-		}
-		/* previously allocated dma buffer wasn't found */
-		DPRINTF("attempt to free invalid dma handle\n");
-		return -EINVAL;
-
-	default:
-		DPRINTF("undefined ioctl\n");
-		return -EINVAL;
-	}
-
-	DPRINTF("success\n");
-	return 0;
-}
-		
-
-static int
-dma_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	struct node_data * nd;
-	struct list_head * iterp;
-	int result;
-	
-	TRACE();
-
-	nd = (struct node_data *)file->private_data;
-	
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-	DPRINTF("offset = %lx\n", vma->vm_pgoff);
-
-	/* get kernel virtual address for the dma buffer (necessary
-	 * for the mmap). */
-	list_for_each(iterp, &nd->u.dma.dma_allocs) {
-		struct dma_allocation * da =
-			list_entry(iterp, struct dma_allocation, list);
-		/* why does mmap shift its offset argument? */
-		if (da->handle == vma->vm_pgoff << PAGE_SHIFT) {
-			DPRINTF("found dma handle\n");
-			if ( (result = mmap_kernel_address(vma,
-							   da->va)) ) {
-				return result; /* failure */
-			} else {
-				/* it seems like at least one of these
-				   should show up in user land....
-				   I'm missing something */
-				*(char *)da->va = 0xaa;
-				strncpy(da->va, "        Toastie!", da->size);
-				if (put_user(0x18badbeeful,
-					     (u64 *)vma->vm_start))
-					DPRINTF("put_user failed?!\n");
-				return 0; /* success */
-			}
-
-		}
-	}
-	DPRINTF("attempt to mmap an invalid dma handle\n");
-	return -EINVAL;
-}
-
-
-static int
-mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va)
-{
-	unsigned long pci_pa;
-
-	TRACE();
-
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-
-	/* the size of the vma doesn't necessarily correspond to the
-           size specified in the mmap call.  So we can't really do any
-           kind of sanity check here.  This is a dangerous driver, and
-           it's very easy for a user process to kill the machine.  */
-
-	DPRINTF("PCI base at virtual address %lx\n", pci_va);
-	/* the __pa macro is intended for region 7 on IA64, so it
-	   doesn't work for region 6 */
-  	/* pci_pa = __pa(pci_va); */
-	/* should be replaced by __tpa or equivalent (preferably a
-	   generic equivalent) */
-	pci_pa = pci_va & ~0xe000000000000000ul;
-	DPRINTF("PCI base at physical address %lx\n", pci_pa);
-
-	/* there are various arch-specific versions of this function
-           defined in linux/drivers/char/mem.c, but it would be nice
-           if all architectures put it in pgtable.h.  it's defined
-           there for ia64.... */
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
-
-	return io_remap_page_range(vma->vm_start, pci_pa, 
-				   vma->vm_end-vma->vm_start,
-				   vma->vm_page_prot);
-}
-
-
-static int
-mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va)
-{
-	unsigned long kernel_pa;
-
-	TRACE();
-
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-
-	/* the size of the vma doesn't necessarily correspond to the
-           size specified in the mmap call.  So we can't really do any
-           kind of sanity check here.  This is a dangerous driver, and
-           it's very easy for a user process to kill the machine.  */
-
-	DPRINTF("mapping virtual address %p\n", kernel_va);
-	kernel_pa = __pa(kernel_va);
-	DPRINTF("mapping physical address %lx\n", kernel_pa);
-
-	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
-
-	return remap_page_range(vma->vm_start, kernel_pa, 
-				vma->vm_end-vma->vm_start,
-				vma->vm_page_prot);
-}	

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)