a5090b0f2a075bbf9f4d247791b652425fd61ec6
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / sn / io / pciba.c
1 /*
2  * arch/ia64/sn/io/pciba.c
3  *
4  * IRIX PCIBA-inspired user mode PCI interface
5  *
6  * requires: devfs
7  *
8  * device nodes show up in /dev/pci/BB/SS.F (where BB is the bus the
9  * device is on, SS is the slot the device is in, and F is the
10  * device's function on a multi-function card).
11  *
12  * when compiled into the kernel, it will only be initialized by the
13  * sgi sn1 specific initialization code.  in this case, device nodes
14  * are under /dev/hw/..../
15  *
16  * This file is subject to the terms and conditions of the GNU General
17  * Public License.  See the file "COPYING" in the main directory of
18  * this archive for more details.
19  *
20  * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
21  *
22  * 03262001 - Initial version by Chad Talbott
23  */
24
25
26 /* jesse's beefs:
27
28    register_pci_device should be documented
29    
30    grossness with do_swap should be documented
31    
32    big, gross union'ized node_data should be replaced with independent
33    structures
34
35    replace global list of nodes with global lists of resources.  could
36    use object oriented approach of allocating and cleaning up
37    resources.
38    
39 */
40
41
42 #include <linux/config.h>
43 #ifndef CONFIG_DEVFS_FS
44 #  error PCIBA requires devfs
45 #endif
46
47 #include <linux/module.h>
48 #include <linux/devfs_fs_kernel.h>
49 #include <linux/pci.h>
50 #include <linux/list.h>
51
52 #include <linux/mm.h>
53 #include <linux/slab.h>
54 #include <linux/vmalloc.h>
55 #include <linux/mman.h>
56 #include <linux/init.h>
57 #include <linux/raw.h>
58 #include <linux/capability.h>
59
60 #include <asm/uaccess.h>
61 #include <asm/io.h>
62 #include <asm/pgalloc.h>
63 #include <asm/page.h>
64
65 #include <asm/sn/pci/pciba.h>
66
67
68 MODULE_DESCRIPTION("User mode PCI interface");
69 MODULE_AUTHOR("Chad Talbott");
70
71
72 #undef DEBUG_PCIBA
73 /* #define DEBUG_PCIBA */
74
75 #undef TRACE_PCIBA
76 /* #define TRACE_PCIBA */
77
78 #if defined(DEBUG_PCIBA)
79 #  define DPRINTF(x...) printk(KERN_DEBUG x)
80 #else
81 #  define DPRINTF(x...)
82 #endif
83
84 #if defined(TRACE_PCIBA)
85 #  if defined(__GNUC__)
86 #    define TRACE()     printk(KERN_DEBUG "%s:%d:%s\n", \
87                                __FILE__, __LINE__, __FUNCTION__)
88 #  else
89 #    define TRACE()     printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
90 #  endif
91 #else
92 #  define TRACE()
93 #endif
94
95
96 typedef enum { failure, success } status;
97 typedef enum { false, true } boolean;
98
99
100 /* major data structures:
101
102    struct node_data -
103    
104         one for each file registered with devfs.  contains everything
105         that any file's fops would need to know about.
106
107    struct dma_allocation -
108
109         a single DMA allocation.  only the 'dma' nodes care about
110         these.  they are there primarily to allow the driver to look
111         up the kernel virtual address of dma buffers allocated by
112         pci_alloc_consistent, as the application is only given the
113         physical address (to program the device's dma, presumably) and
114         cannot supply the kernel virtual address when freeing the
115         buffer.
116
117         it's also useful to maintain a list of buffers allocated
118         through a specific node to allow some sanity checking by this
119         driver.  this prevents (for example) a broken application from
120         freeing buffers that it didn't allocate, or buffers allocated
121         on another node.
122    
123    global_node_list -
124
125         a list of all nodes allocated.  this allows the driver to free
126         all the memory it has 'kmalloc'd in case of an error, or on
127         module removal.
128
129    global_dma_list -
130
131         a list of all dma buffers allocated by this driver.  this
132         allows the driver to 'pci_free_consistent' all buffers on
133         module removal or error.
134
135 */
136
137
138 struct node_data {
139         /* flat list of all the device nodes.  makes it easy to free
140            them all when we're unregistered */
141         struct list_head global_node_list;
142         devfs_handle_t devfs_handle;
143
144         void (* cleanup)(struct node_data *);
145
146         union {
147                 struct {
148                         struct pci_dev * dev;
149                         struct list_head dma_allocs;
150                         boolean mmapped;
151                 } dma;
152                 struct {
153                         struct pci_dev * dev;
154                         u32 saved_rom_base_reg;
155                         boolean mmapped;
156                 } rom;
157                 struct {
158                         struct resource * res;
159                 } base;
160                 struct {
161                         struct pci_dev * dev;
162                 } config;
163         } u;
164 };
165
166 struct dma_allocation {
167         struct list_head list;
168
169         dma_addr_t handle;
170         void * va;
171         size_t size;
172 };
173
174
175 static LIST_HEAD(global_node_list);
176 static LIST_HEAD(global_dma_list);
177
178
179 /* module entry points */
180 int __init pciba_init(void);
181 void __exit pciba_exit(void);
182
183 static status __init register_with_devfs(void);
184 static void __exit unregister_with_devfs(void);
185
186 static status __init register_pci_device(devfs_handle_t device_dir_handle,
187                                          struct pci_dev * dev);
188
189 /* file operations */
190 static int generic_open(struct inode * inode, struct file * file);
191 static int rom_mmap(struct file * file, struct vm_area_struct * vma);
192 static int rom_release(struct inode * inode, struct file * file);
193 static int base_mmap(struct file * file, struct vm_area_struct * vma);
194 static int config_ioctl(struct inode * inode, struct file * file, 
195                         unsigned int cmd, 
196                         unsigned long arg);
197 static int dma_ioctl(struct inode * inode, struct file * file, 
198                      unsigned int cmd, 
199                      unsigned long arg);
200 static int dma_mmap(struct file * file, struct vm_area_struct * vma);
201
202 /* support routines */
203 static int mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va);
204 static int mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va);
205
206 #ifdef DEBUG_PCIBA
207 static void dump_nodes(struct list_head * nodes);
208 static void dump_allocations(struct list_head * dalp);
209 #endif
210
211 /* file operations for each type of node */
212 static struct file_operations rom_fops = {
213         owner:          THIS_MODULE,
214         mmap:           rom_mmap,
215         open:           generic_open,
216         release:        rom_release
217 };
218  
219
220 static struct file_operations base_fops = {
221         owner:          THIS_MODULE,
222         mmap:           base_mmap,
223         open:           generic_open
224 };
225
226
227 static struct file_operations config_fops = {
228         owner:          THIS_MODULE,
229         ioctl:          config_ioctl,
230         open:           generic_open
231 };      
232
233 static struct file_operations dma_fops = {
234         owner:          THIS_MODULE,
235         ioctl:          dma_ioctl,
236         mmap:           dma_mmap,
237         open:           generic_open
238 };      
239
240
241 module_init(pciba_init);
242 module_exit(pciba_exit);
243
244
245 int __init
246 pciba_init(void)
247 {
248         TRACE();
249
250         if (register_with_devfs() == failure)
251                 return 1; /* failure */
252
253         printk("PCIBA (a user mode PCI interface) initialized.\n");
254
255         return 0; /* success */
256 }
257
258
259 void __exit
260 pciba_exit(void)
261 {
262         TRACE();
263
264         /* FIXME: should also free all that memory that we allocated
265            ;) */
266         unregister_with_devfs();
267 }
268
269
270 # if 0
271 static void __exit
272 free_nodes(void)
273 {
274         struct node_data * nd;
275         
276         TRACE();
277
278         list_for_each(nd, &node_list) {
279                 kfree(list_entry(nd, struct nd, node_list));
280         }
281 }
282 #endif
283
284 #if !defined(CONFIG_IA64_SGI_SN1)
285
286 static status __init
287 register_with_devfs(void)
288 {
289         struct pci_dev * dev;
290         devfs_handle_t device_dir_handle;
291         char devfs_path[40];
292
293         TRACE();
294
295         if (!devfs_mk_dir(NULL, "pci", NULL))
296                 return failure;
297
298         /* FIXME: don't forget /dev/pci/mem & /dev/pci/io */
299
300         pci_for_each_dev(dev) {
301                 sprintf(devfs_path, "pci/%02x/%02x.%x",
302                         dev->bus->number,
303                         PCI_SLOT(dev->devfn),
304                         PCI_FUNC(dev->devfn));
305     
306                 device_dir_handle =
307                         devfs_mk_dir(NULL, devfs_path, NULL);
308                 if (device_dir_handle == NULL)
309                         return failure;
310
311                 if (register_pci_device(device_dir_handle, dev) == failure) {
312                         devfs_remove("pci");
313                         return failure;
314                 }
315         }
316
317         return success;
318 }
319
320 #else
321
322 extern devfs_handle_t
323 devfn_to_vertex(unsigned char busnum, unsigned int devfn);
324
325 static status __init
326 register_with_devfs(void)
327 {
328         struct pci_dev * dev;
329         devfs_handle_t device_dir_handle;
330
331         TRACE();
332
333         /* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */
334
335         pci_for_each_dev(dev) {
336                 device_dir_handle = devfn_to_vertex(dev->bus->number,
337                                                     dev->devfn);
338                 if (device_dir_handle == NULL)
339                         return failure;
340         
341                 if (register_pci_device(device_dir_handle, dev) == failure) {
342                         devfs_remove("pci");
343                         return failure;
344                 }
345         }
346
347         return success;
348 }
349
350 static void __exit
351 unregister_with_devfs(void)
352 {
353         struct list_head * lhp;
354         struct node_data * nd;
355         
356         TRACE();
357
358         list_for_each(lhp, &global_node_list) {
359                 nd = list_entry(lhp, struct node_data, global_node_list);
360                 devfs_unregister(nd->devfs_handle);
361         }
362
363 }
364
365
366 struct node_data * new_node(void)
367 {
368         struct node_data * node;
369         
370         TRACE();
371         
372         node = kmalloc(sizeof(struct node_data), GFP_KERNEL);
373         if (node == NULL)
374                 return NULL;
375         list_add(&node->global_node_list, &global_node_list);
376         return node;
377 }
378
379
380 void dma_cleanup(struct node_data * dma_node)
381 {
382         TRACE();
383
384         /* FIXME: should free these allocations */
385 #ifdef DEBUG_PCIBA
386         dump_allocations(&dma_node->u.dma.dma_allocs);
387 #endif
388         devfs_unregister(dma_node->devfs_handle);
389 }
390
391
392 void init_dma_node(struct node_data * node,
393                    struct pci_dev * dev, devfs_handle_t dh)
394 {
395         TRACE();
396
397         node->devfs_handle = dh;
398         node->u.dma.dev = dev;
399         node->cleanup = dma_cleanup;
400         INIT_LIST_HEAD(&node->u.dma.dma_allocs);
401 }
402
403
404 void rom_cleanup(struct node_data * rom_node)
405 {
406         TRACE();
407
408         if (rom_node->u.rom.mmapped)
409                 pci_write_config_dword(rom_node->u.rom.dev,
410                                        PCI_ROM_ADDRESS,
411                                        rom_node->u.rom.saved_rom_base_reg);
412         devfs_unregister(rom_node->devfs_handle);
413 }
414
415
416 void init_rom_node(struct node_data * node,
417                    struct pci_dev * dev, devfs_handle_t dh)
418 {
419         TRACE();
420
421         node->devfs_handle = dh;
422         node->u.rom.dev = dev;
423         node->cleanup = rom_cleanup;
424         node->u.rom.mmapped = false;
425 }
426
427
428 static status __init
429 register_pci_device(devfs_handle_t device_dir_handle, struct pci_dev * dev)
430 {
431         struct node_data * nd;
432         char devfs_path[20];
433         devfs_handle_t node_devfs_handle;
434         int ri;
435
436         TRACE();
437
438
439         /* register nodes for all the device's base address registers */
440         for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
441                 if (pci_resource_len(dev, ri) != 0) {
442                         sprintf(devfs_path, "base/%d", ri);
443                         if (devfs_register(device_dir_handle, devfs_path,
444                                            DEVFS_FL_NONE,
445                                            0, 0,
446                                            S_IFREG | S_IRUSR | S_IWUSR,
447                                            &base_fops, 
448                                            &dev->resource[ri]) == NULL)
449                                 return failure;
450                 }
451         }
452         
453         /* register a node corresponding to the first MEM resource on
454            the device */
455         for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
456                 if (dev->resource[ri].flags & IORESOURCE_MEM &&
457                     pci_resource_len(dev, ri) != 0) {
458                         if (devfs_register(device_dir_handle, "mem",
459                                            DEVFS_FL_NONE, 0, 0,
460                                            S_IFREG | S_IRUSR | S_IWUSR,
461                                            &base_fops, 
462                                            &dev->resource[ri]) == NULL)
463                                 return failure;
464                         break;
465                 }
466         }
467
468         /* also register a node corresponding to the first IO resource
469            on the device */
470         for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
471                 if (dev->resource[ri].flags & IORESOURCE_IO &&
472                     pci_resource_len(dev, ri) != 0) {
473                         if (devfs_register(device_dir_handle, "io",
474                                            DEVFS_FL_NONE, 0, 0,
475                                            S_IFREG | S_IRUSR | S_IWUSR,
476                                            &base_fops, 
477                                            &dev->resource[ri]) == NULL)
478                                 return failure;
479                         break;
480                 }
481         }
482
483         /* register a node corresponding to the device's ROM resource,
484            if present */
485         if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) {
486                 nd = new_node();
487                 if (nd == NULL)
488                         return failure;
489                 node_devfs_handle = devfs_register(device_dir_handle, "rom",
490                                                    DEVFS_FL_NONE, 0, 0,
491                                                    S_IFREG | S_IRUSR,
492                                                    &rom_fops, nd);
493                 if (node_devfs_handle == NULL)
494                         return failure;
495                 init_rom_node(nd, dev, node_devfs_handle);
496         }
497
498         /* register a node that allows ioctl's to read and write to
499            the device's config space */
500         if (devfs_register(device_dir_handle, "config", DEVFS_FL_NONE,
501                            0, 0, S_IFREG | S_IRUSR | S_IWUSR,
502                            &config_fops, dev) == NULL)
503                 return failure;
504
505
506         /* finally, register a node that allows ioctl's to allocate
507            and free DMA buffers, as well as memory map those
508            buffers. */
509         nd = new_node();
510         if (nd == NULL)
511                 return failure;
512         node_devfs_handle =
513                 devfs_register(device_dir_handle, "dma", DEVFS_FL_NONE,
514                                0, 0, S_IFREG | S_IRUSR | S_IWUSR,
515                                &dma_fops, nd);
516         if (node_devfs_handle == NULL)
517                 return failure;
518         init_dma_node(nd, dev, node_devfs_handle);
519
520 #ifdef DEBUG_PCIBA
521         dump_nodes(&global_node_list);
522 #endif
523         
524         return success;
525 }
526
527
528 static int
529 generic_open(struct inode * inode, struct file * file)
530 {
531         TRACE();
532
533         /* FIXME: should check that they're not trying to open the ROM
534            writable */
535
536         return 0; /* success */
537 }
538
539
540 static int
541 rom_mmap(struct file * file, struct vm_area_struct * vma)
542 {
543         unsigned long pci_pa;
544         struct node_data * nd;
545
546         TRACE();
547
548         nd = (struct node_data * )file->private_data;
549
550         pci_pa = pci_resource_start(nd->u.rom.dev, PCI_ROM_RESOURCE);
551
552         if (!nd->u.rom.mmapped) {
553                 nd->u.rom.mmapped = true;
554                 DPRINTF("Enabling ROM address decoder.\n");
555                 DPRINTF(
556 "rom_mmap: FIXME: some cards do not allow both ROM and memory addresses to\n"
557 "rom_mmap: FIXME: be enabled simultaneously, as they share a decoder.\n");
558                 pci_read_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
559                                       &nd->u.rom.saved_rom_base_reg);
560                 DPRINTF("ROM base address contains %x\n",
561                         nd->u.rom.saved_rom_base_reg);
562                 pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
563                                        nd->u.rom.saved_rom_base_reg |
564                                        PCI_ROM_ADDRESS_ENABLE);
565         }
566         
567         return mmap_pci_address(vma, pci_pa);
568 }
569
570
571 static int
572 rom_release(struct inode * inode, struct file * file)
573 {
574         struct node_data * nd;
575
576         TRACE();
577
578         nd = (struct node_data * )file->private_data;
579
580         if (nd->u.rom.mmapped) {
581                 nd->u.rom.mmapped = false;
582                 DPRINTF("Disabling ROM address decoder.\n");
583                 pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
584                                        nd->u.rom.saved_rom_base_reg);
585         }
586         return 0; /* indicate success */
587 }
588
589
590 static int
591 base_mmap(struct file * file, struct vm_area_struct * vma)
592 {
593         struct resource * resource;
594
595         TRACE();
596
597         resource = (struct resource *)file->private_data;
598
599         return mmap_pci_address(vma, resource->start);
600 }
601
602
603 static int
604 config_ioctl(struct inode * inode, struct file * file, 
605              unsigned int cmd, 
606              unsigned long arg)
607 {
608         struct pci_dev * dev;
609
610         union cfg_data {
611                 uint8_t byte;
612                 uint16_t word;
613                 uint32_t dword;
614         } read_data, write_data;
615
616         int dir, size, offset;
617
618         TRACE();
619
620         DPRINTF("cmd = %x (DIR = %x, TYPE = %x, NR = %x, SIZE = %x)\n", 
621                 cmd, 
622                 _IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
623         DPRINTF("arg = %lx\n", arg);
624
625         dev = (struct pci_dev *)file->private_data;
626
627         /* PCIIOCCFG{RD,WR}: read and/or write PCI configuration
628            space. If both, the read happens first (this becomes a swap
629            operation, atomic with respect to other updates through
630            this path).  */
631
632         dir = _IOC_DIR(cmd);
633
634 #define do_swap(suffix, type)                                           \
635         do {                                                            \
636                 if (dir & _IOC_READ) {                                  \
637                         pci_read_config_##suffix(dev, _IOC_NR(cmd),     \
638                                                  &read_data.suffix);    \
639                 }                                                       \
640                 if (dir & _IOC_WRITE) {                                 \
641                         get_user(write_data.suffix, (type)arg);         \
642                         pci_write_config_##suffix(dev, _IOC_NR(cmd),    \
643                                                   write_data.suffix);   \
644                 }                                                       \
645                 if (dir & _IOC_READ) {                                  \
646                         put_user(read_data.suffix, (type)arg);          \
647                 }                                                       \
648         } while (0)
649
650         size = _IOC_SIZE(cmd);
651         offset = _IOC_NR(cmd);
652
653         DPRINTF("sanity check\n");
654         if (((size > 0) || (size <= 4)) &&
655             ((offset + size) <= 256) &&
656             (dir & (_IOC_READ | _IOC_WRITE))) {
657
658                 switch (size)
659                 {
660                 case 1:
661                         do_swap(byte, uint8_t *);
662                         break;
663                 case 2:
664                         do_swap(word, uint16_t *);
665                         break;
666                 case 4:
667                         do_swap(dword, uint32_t *);
668                         break;
669                 default:
670                         DPRINTF("invalid ioctl\n");
671                         return -EINVAL;
672                 }
673         } else
674                 return -EINVAL;
675                 
676         return 0;
677 }
678
679
680 #ifdef DEBUG_PCIBA
681 static void
682 dump_allocations(struct list_head * dalp)
683 {
684         struct dma_allocation * dap;
685         struct list_head * p;
686         
687         printk("{\n");
688         list_for_each(p, dalp) {
689                 dap = list_entry(p, struct dma_allocation, 
690                                  list);
691                 printk("  handle = %lx, va = %p\n",
692                        dap->handle, dap->va);
693         }
694         printk("}\n");
695 }
696
697 static void
698 dump_nodes(struct list_head * nodes)
699 {
700         struct node_data * ndp;
701         struct list_head * p;
702         
703         printk("{\n");
704         list_for_each(p, nodes) {
705                 ndp = list_entry(p, struct node_data, 
706                                  global_node_list);
707                 printk("  %p\n", (void *)ndp);
708         }
709         printk("}\n");
710 }
711
712
713 #if 0
714 #define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
715
716 static void
717 test_list(void)
718 {
719         u64 i;
720         LIST_HEAD(the_list);
721
722         for (i = 0; i < 5; i++) {
723                 struct dma_allocation * new_alloc;
724                 NEW(new_alloc);
725                 new_alloc->va = (void *)i;
726                 new_alloc->handle = 5*i;
727                 printk("%d - the_list->next = %lx\n", i, the_list.next);
728                 list_add(&new_alloc->list, &the_list);
729         }
730         dump_allocations(&the_list);
731 }
732 #endif
733 #endif
734
735
736 static LIST_HEAD(dma_buffer_list);
737
738
739 static int
740 dma_ioctl(struct inode * inode, struct file * file, 
741           unsigned int cmd, 
742           unsigned long arg)
743 {
744         struct node_data * nd;
745         uint64_t argv;
746         int result;
747         struct dma_allocation * dma_alloc;
748         struct list_head * iterp;
749
750         TRACE();
751
752         DPRINTF("cmd = %x\n", cmd);
753         DPRINTF("arg = %lx\n", arg);
754
755         nd = (struct node_data *)file->private_data;
756
757 #ifdef DEBUG_PCIBA
758         DPRINTF("at dma_ioctl entry\n");
759         dump_allocations(&nd->u.dma.dma_allocs);
760 #endif
761
762         switch (cmd) {
763         case PCIIOCDMAALLOC:
764                 /* PCIIOCDMAALLOC: allocate a chunk of physical memory
765                    and set it up for DMA. Return the PCI address that
766                    gets to it.  */
767                 DPRINTF("case PCIIOCDMAALLOC (%lx)\n", PCIIOCDMAALLOC);
768                 
769                 if ( (result = get_user(argv, (uint64_t *)arg)) )
770                         return result;
771                 DPRINTF("argv (size of buffer) = %lx\n", argv);
772
773                 dma_alloc = (struct dma_allocation *)
774                         kmalloc(sizeof(struct dma_allocation), GFP_KERNEL);
775                 if (dma_alloc == NULL)
776                         return -ENOMEM;
777
778                 dma_alloc->size = (size_t)argv;
779                 dma_alloc->va = pci_alloc_consistent(nd->u.dma.dev,
780                                                      dma_alloc->size,
781                                                      &dma_alloc->handle);
782                 DPRINTF("dma_alloc->va = %p, dma_alloc->handle = %lx\n",
783                         dma_alloc->va, dma_alloc->handle);
784                 if (dma_alloc->va == NULL) {
785                         kfree(dma_alloc);
786                         return -ENOMEM;
787                 }
788
789                 list_add(&dma_alloc->list, &nd->u.dma.dma_allocs);
790                 if ( (result = put_user((uint64_t)dma_alloc->handle, 
791                                       (uint64_t *)arg)) ) {
792                         DPRINTF("put_user failed\n");
793                         pci_free_consistent(nd->u.dma.dev, (size_t)argv,
794                                             dma_alloc->va, dma_alloc->handle);
795                         kfree(dma_alloc);
796                         return result;
797                 }
798
799 #ifdef DEBUG_PCIBA
800                 DPRINTF("after insertion\n");
801                 dump_allocations(&nd->u.dma.dma_allocs);
802 #endif
803                 break;
804
805         case PCIIOCDMAFREE:
806                 DPRINTF("case PCIIOCDMAFREE (%lx)\n", PCIIOCDMAFREE);
807
808                 if ( (result = get_user(argv, (uint64_t *)arg)) ) {
809                         DPRINTF("get_user failed\n");
810                         return result;
811                 }
812
813                 DPRINTF("argv (physical address of DMA buffer) = %lx\n", argv);
814                 list_for_each(iterp, &nd->u.dma.dma_allocs) {
815                         struct dma_allocation * da =
816                                 list_entry(iterp, struct dma_allocation, list);
817                         if (da->handle == argv) {
818                                 pci_free_consistent(nd->u.dma.dev, da->size,
819                                                     da->va, da->handle);
820                                 list_del(&da->list);
821                                 kfree(da);
822 #ifdef DEBUG_PCIBA
823                                 DPRINTF("after deletion\n");
824                                 dump_allocations(&nd->u.dma.dma_allocs);
825 #endif
826                                 return 0; /* success */
827                         }
828                 }
829                 /* previously allocated dma buffer wasn't found */
830                 DPRINTF("attempt to free invalid dma handle\n");
831                 return -EINVAL;
832
833         default:
834                 DPRINTF("undefined ioctl\n");
835                 return -EINVAL;
836         }
837
838         DPRINTF("success\n");
839         return 0;
840 }
841                 
842
843 static int
844 dma_mmap(struct file * file, struct vm_area_struct * vma)
845 {
846         struct node_data * nd;
847         struct list_head * iterp;
848         int result;
849         
850         TRACE();
851
852         nd = (struct node_data *)file->private_data;
853         
854         DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
855         DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
856         DPRINTF("offset = %lx\n", vma->vm_pgoff);
857
858         /* get kernel virtual address for the dma buffer (necessary
859          * for the mmap). */
860         list_for_each(iterp, &nd->u.dma.dma_allocs) {
861                 struct dma_allocation * da =
862                         list_entry(iterp, struct dma_allocation, list);
863                 /* why does mmap shift its offset argument? */
864                 if (da->handle == vma->vm_pgoff << PAGE_SHIFT) {
865                         DPRINTF("found dma handle\n");
866                         if ( (result = mmap_kernel_address(vma,
867                                                            da->va)) ) {
868                                 return result; /* failure */
869                         } else {
870                                 /* it seems like at least one of these
871                                    should show up in user land....
872                                    I'm missing something */
873                                 *(char *)da->va = 0xaa;
874                                 strncpy(da->va, "        Toastie!", da->size);
875                                 if (put_user(0x18badbeeful,
876                                              (u64 *)vma->vm_start))
877                                         DPRINTF("put_user failed?!\n");
878                                 return 0; /* success */
879                         }
880
881                 }
882         }
883         DPRINTF("attempt to mmap an invalid dma handle\n");
884         return -EINVAL;
885 }
886
887
888 static int
889 mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va)
890 {
891         unsigned long pci_pa;
892
893         TRACE();
894
895         DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
896         DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
897
898         /* the size of the vma doesn't necessarily correspond to the
899            size specified in the mmap call.  So we can't really do any
900            kind of sanity check here.  This is a dangerous driver, and
901            it's very easy for a user process to kill the machine.  */
902
903         DPRINTF("PCI base at virtual address %lx\n", pci_va);
904         /* the __pa macro is intended for region 7 on IA64, so it
905            doesn't work for region 6 */
906         /* pci_pa = __pa(pci_va); */
907         /* should be replaced by __tpa or equivalent (preferably a
908            generic equivalent) */
909         pci_pa = pci_va & ~0xe000000000000000ul;
910         DPRINTF("PCI base at physical address %lx\n", pci_pa);
911
912         /* there are various arch-specific versions of this function
913            defined in linux/drivers/char/mem.c, but it would be nice
914            if all architectures put it in pgtable.h.  it's defined
915            there for ia64.... */
916         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
917
918         vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
919
920         return io_remap_page_range(vma->vm_start, pci_pa, 
921                                    vma->vm_end-vma->vm_start,
922                                    vma->vm_page_prot);
923 }
924
925
926 static int
927 mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va)
928 {
929         unsigned long kernel_pa;
930
931         TRACE();
932
933         DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
934         DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
935
936         /* the size of the vma doesn't necessarily correspond to the
937            size specified in the mmap call.  So we can't really do any
938            kind of sanity check here.  This is a dangerous driver, and
939            it's very easy for a user process to kill the machine.  */
940
941         DPRINTF("mapping virtual address %p\n", kernel_va);
942         kernel_pa = __pa(kernel_va);
943         DPRINTF("mapping physical address %lx\n", kernel_pa);
944
945         vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
946
947         return remap_page_range(vma->vm_start, kernel_pa, 
948                                 vma->vm_end-vma->vm_start,
949                                 vma->vm_page_prot);
950 }