Staging: netwave: add TODO file
[linux-2.6.git] / drivers / staging / vme / vme.c
1 /*
2  * VME Bridge Framework
3  *
4  * Author: Martyn Welch <martyn.welch@gefanuc.com>
5  * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
6  *
7  * Based on work by Tom Armistead and Ajit Prem
8  * Copyright 2004 Motorola Inc.
9  *
10  * This program is free software; you can redistribute  it and/or modify it
11  * under  the terms of  the GNU General  Public License as published by the
12  * Free Software Foundation;  either version 2 of the  License, or (at your
13  * option) any later version.
14  */
15
16 #include <linux/version.h>
17 #include <linux/module.h>
18 #include <linux/moduleparam.h>
19 #include <linux/mm.h>
20 #include <linux/types.h>
21 #include <linux/kernel.h>
22 #include <linux/errno.h>
23 #include <linux/pci.h>
24 #include <linux/poll.h>
25 #include <linux/highmem.h>
26 #include <linux/interrupt.h>
27 #include <linux/pagemap.h>
28 #include <linux/device.h>
29 #include <linux/dma-mapping.h>
30 #include <linux/syscalls.h>
31 #include <linux/mutex.h>
32 #include <linux/spinlock.h>
33
34 #include "vme.h"
35 #include "vme_bridge.h"
36
37 /* Bitmask and mutex to keep track of bridge numbers */
38 static unsigned int vme_bus_numbers;
39 DEFINE_MUTEX(vme_bus_num_mtx);
40
41 static void __exit vme_exit (void);
42 static int __init vme_init (void);
43
44
45 /*
46  * Find the bridge resource associated with a specific device resource
47  */
48 static struct vme_bridge *dev_to_bridge(struct device *dev)
49 {
50         return dev->platform_data;
51 }
52
53 /*
54  * Find the bridge that the resource is associated with.
55  */
56 static struct vme_bridge *find_bridge(struct vme_resource *resource)
57 {
58         /* Get list to search */
59         switch (resource->type) {
60         case VME_MASTER:
61                 return list_entry(resource->entry, struct vme_master_resource,
62                         list)->parent;
63                 break;
64         case VME_SLAVE:
65                 return list_entry(resource->entry, struct vme_slave_resource,
66                         list)->parent;
67                 break;
68         case VME_DMA:
69                 return list_entry(resource->entry, struct vme_dma_resource,
70                         list)->parent;
71                 break;
72         case VME_LM:
73                 return list_entry(resource->entry, struct vme_lm_resource,
74                         list)->parent;
75                 break;
76         default:
77                 printk(KERN_ERR "Unknown resource type\n");
78                 return NULL;
79                 break;
80         }
81 }
82
83 /*
84  * Allocate a contiguous block of memory for use by the driver. This is used to
85  * create the buffers for the slave windows.
86  *
87  * XXX VME bridges could be available on buses other than PCI. At the momment
88  *     this framework only supports PCI devices.
89  */
90 void * vme_alloc_consistent(struct vme_resource *resource, size_t size,
91         dma_addr_t *dma)
92 {
93         struct vme_bridge *bridge;
94         struct pci_dev *pdev;
95
96         if(resource == NULL) {
97                 printk("No resource\n");
98                 return NULL;
99         }
100
101         bridge = find_bridge(resource);
102         if(bridge == NULL) {
103                 printk("Can't find bridge\n");
104                 return NULL;
105         }
106
107         /* Find pci_dev container of dev */
108         if (bridge->parent == NULL) {
109                 printk("Dev entry NULL\n");
110                 return NULL;
111         }
112         pdev = container_of(bridge->parent, struct pci_dev, dev);
113
114         return pci_alloc_consistent(pdev, size, dma);
115 }
116 EXPORT_SYMBOL(vme_alloc_consistent);
117
118 /*
119  * Free previously allocated contiguous block of memory.
120  *
121  * XXX VME bridges could be available on buses other than PCI. At the momment
122  *     this framework only supports PCI devices.
123  */
124 void vme_free_consistent(struct vme_resource *resource, size_t size,
125         void *vaddr, dma_addr_t dma)
126 {
127         struct vme_bridge *bridge;
128         struct pci_dev *pdev;
129
130         if(resource == NULL) {
131                 printk("No resource\n");
132                 return;
133         }
134
135         bridge = find_bridge(resource);
136         if(bridge == NULL) {
137                 printk("Can't find bridge\n");
138                 return;
139         }
140
141         /* Find pci_dev container of dev */
142         pdev = container_of(bridge->parent, struct pci_dev, dev);
143
144         pci_free_consistent(pdev, size, vaddr, dma);
145 }
146 EXPORT_SYMBOL(vme_free_consistent);
147
148 size_t vme_get_size(struct vme_resource *resource)
149 {
150         int enabled, retval;
151         unsigned long long base, size;
152         dma_addr_t buf_base;
153         vme_address_t aspace;
154         vme_cycle_t cycle;
155         vme_width_t dwidth;
156
157         switch (resource->type) {
158         case VME_MASTER:
159                 retval = vme_master_get(resource, &enabled, &base, &size,
160                         &aspace, &cycle, &dwidth);
161
162                 return size;
163                 break;
164         case VME_SLAVE:
165                 retval = vme_slave_get(resource, &enabled, &base, &size,
166                         &buf_base, &aspace, &cycle);
167
168                 return size;
169                 break;
170         case VME_DMA:
171                 return 0;
172                 break;
173         default:
174                 printk(KERN_ERR "Unknown resource type\n");
175                 return 0;
176                 break;
177         }
178 }
179 EXPORT_SYMBOL(vme_get_size);
180
181 static int vme_check_window(vme_address_t aspace, unsigned long long vme_base,
182         unsigned long long size)
183 {
184         int retval = 0;
185
186         switch (aspace) {
187         case VME_A16:
188                 if (((vme_base + size) > VME_A16_MAX) ||
189                                 (vme_base > VME_A16_MAX))
190                         retval = -EFAULT;
191                 break;
192         case VME_A24:
193                 if (((vme_base + size) > VME_A24_MAX) ||
194                                 (vme_base > VME_A24_MAX))
195                         retval = -EFAULT;
196                 break;
197         case VME_A32:
198                 if (((vme_base + size) > VME_A32_MAX) ||
199                                 (vme_base > VME_A32_MAX))
200                         retval = -EFAULT;
201                 break;
202         case VME_A64:
203                 /*
204                  * Any value held in an unsigned long long can be used as the
205                  * base
206                  */
207                 break;
208         case VME_CRCSR:
209                 if (((vme_base + size) > VME_CRCSR_MAX) ||
210                                 (vme_base > VME_CRCSR_MAX))
211                         retval = -EFAULT;
212                 break;
213         case VME_USER1:
214         case VME_USER2:
215         case VME_USER3:
216         case VME_USER4:
217                 /* User Defined */
218                 break;
219         default:
220                 printk("Invalid address space\n");
221                 retval = -EINVAL;
222                 break;
223         }
224
225         return retval;
226 }
227
228 /*
229  * Request a slave image with specific attributes, return some unique
230  * identifier.
231  */
232 struct vme_resource * vme_slave_request(struct device *dev,
233         vme_address_t address, vme_cycle_t cycle)
234 {
235         struct vme_bridge *bridge;
236         struct list_head *slave_pos = NULL;
237         struct vme_slave_resource *allocated_image = NULL;
238         struct vme_slave_resource *slave_image = NULL;
239         struct vme_resource *resource = NULL;
240
241         bridge = dev_to_bridge(dev);
242         if (bridge == NULL) {
243                 printk(KERN_ERR "Can't find VME bus\n");
244                 goto err_bus;
245         }
246
247         /* Loop through slave resources */
248         list_for_each(slave_pos, &(bridge->slave_resources)) {
249                 slave_image = list_entry(slave_pos,
250                         struct vme_slave_resource, list);
251
252                 if (slave_image == NULL) {
253                         printk("Registered NULL Slave resource\n");
254                         continue;
255                 }
256
257                 /* Find an unlocked and compatible image */
258                 mutex_lock(&(slave_image->mtx));
259                 if(((slave_image->address_attr & address) == address) &&
260                         ((slave_image->cycle_attr & cycle) == cycle) &&
261                         (slave_image->locked == 0)) {
262
263                         slave_image->locked = 1;
264                         mutex_unlock(&(slave_image->mtx));
265                         allocated_image = slave_image;
266                         break;
267                 }
268                 mutex_unlock(&(slave_image->mtx));
269         }
270
271         /* No free image */
272         if (allocated_image == NULL)
273                 goto err_image;
274
275         resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
276         if (resource == NULL) {
277                 printk(KERN_WARNING "Unable to allocate resource structure\n");
278                 goto err_alloc;
279         }
280         resource->type = VME_SLAVE;
281         resource->entry = &(allocated_image->list);
282
283         return resource;
284
285 err_alloc:
286         /* Unlock image */
287         mutex_lock(&(slave_image->mtx));
288         slave_image->locked = 0;
289         mutex_unlock(&(slave_image->mtx));
290 err_image:
291 err_bus:
292         return NULL;
293 }
294 EXPORT_SYMBOL(vme_slave_request);
295
296 int vme_slave_set (struct vme_resource *resource, int enabled,
297         unsigned long long vme_base, unsigned long long size,
298         dma_addr_t buf_base, vme_address_t aspace, vme_cycle_t cycle)
299 {
300         struct vme_bridge *bridge = find_bridge(resource);
301         struct vme_slave_resource *image;
302         int retval;
303
304         if (resource->type != VME_SLAVE) {
305                 printk("Not a slave resource\n");
306                 return -EINVAL;
307         }
308
309         image = list_entry(resource->entry, struct vme_slave_resource, list);
310
311         if (bridge->slave_set == NULL) {
312                 printk("Function not supported\n");
313                 return -ENOSYS;
314         }
315
316         if(!(((image->address_attr & aspace) == aspace) &&
317                 ((image->cycle_attr & cycle) == cycle))) {
318                 printk("Invalid attributes\n");
319                 return -EINVAL;
320         }
321
322         retval = vme_check_window(aspace, vme_base, size);
323         if(retval)
324                 return retval;
325
326         return bridge->slave_set(image, enabled, vme_base, size, buf_base,
327                 aspace, cycle);
328 }
329 EXPORT_SYMBOL(vme_slave_set);
330
331 int vme_slave_get (struct vme_resource *resource, int *enabled,
332         unsigned long long *vme_base, unsigned long long *size,
333         dma_addr_t *buf_base, vme_address_t *aspace, vme_cycle_t *cycle)
334 {
335         struct vme_bridge *bridge = find_bridge(resource);
336         struct vme_slave_resource *image;
337
338         if (resource->type != VME_SLAVE) {
339                 printk("Not a slave resource\n");
340                 return -EINVAL;
341         }
342
343         image = list_entry(resource->entry, struct vme_slave_resource, list);
344
345         if (bridge->slave_get == NULL) {
346                 printk("vme_slave_get not supported\n");
347                 return -EINVAL;
348         }
349
350         return bridge->slave_get(image, enabled, vme_base, size, buf_base,
351                 aspace, cycle);
352 }
353 EXPORT_SYMBOL(vme_slave_get);
354
355 void vme_slave_free(struct vme_resource *resource)
356 {
357         struct vme_slave_resource *slave_image;
358
359         if (resource->type != VME_SLAVE) {
360                 printk("Not a slave resource\n");
361                 return;
362         }
363
364         slave_image = list_entry(resource->entry, struct vme_slave_resource,
365                 list);
366         if (slave_image == NULL) {
367                 printk("Can't find slave resource\n");
368                 return;
369         }
370
371         /* Unlock image */
372         mutex_lock(&(slave_image->mtx));
373         if (slave_image->locked == 0)
374                 printk(KERN_ERR "Image is already free\n");
375
376         slave_image->locked = 0;
377         mutex_unlock(&(slave_image->mtx));
378
379         /* Free up resource memory */
380         kfree(resource);
381 }
382 EXPORT_SYMBOL(vme_slave_free);
383
384 /*
385  * Request a master image with specific attributes, return some unique
386  * identifier.
387  */
388 struct vme_resource * vme_master_request(struct device *dev,
389         vme_address_t address, vme_cycle_t cycle, vme_width_t dwidth)
390 {
391         struct vme_bridge *bridge;
392         struct list_head *master_pos = NULL;
393         struct vme_master_resource *allocated_image = NULL;
394         struct vme_master_resource *master_image = NULL;
395         struct vme_resource *resource = NULL;
396
397         bridge = dev_to_bridge(dev);
398         if (bridge == NULL) {
399                 printk(KERN_ERR "Can't find VME bus\n");
400                 goto err_bus;
401         }
402
403         /* Loop through master resources */
404         list_for_each(master_pos, &(bridge->master_resources)) {
405                 master_image = list_entry(master_pos,
406                         struct vme_master_resource, list);
407
408                 if (master_image == NULL) {
409                         printk(KERN_WARNING "Registered NULL master resource\n");
410                         continue;
411                 }
412
413                 /* Find an unlocked and compatible image */
414                 spin_lock(&(master_image->lock));
415                 if(((master_image->address_attr & address) == address) &&
416                         ((master_image->cycle_attr & cycle) == cycle) &&
417                         ((master_image->width_attr & dwidth) == dwidth) &&
418                         (master_image->locked == 0)) {
419
420                         master_image->locked = 1;
421                         spin_unlock(&(master_image->lock));
422                         allocated_image = master_image;
423                         break;
424                 }
425                 spin_unlock(&(master_image->lock));
426         }
427
428         /* Check to see if we found a resource */
429         if (allocated_image == NULL) {
430                 printk(KERN_ERR "Can't find a suitable resource\n");
431                 goto err_image;
432         }
433
434         resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
435         if (resource == NULL) {
436                 printk(KERN_ERR "Unable to allocate resource structure\n");
437                 goto err_alloc;
438         }
439         resource->type = VME_MASTER;
440         resource->entry = &(allocated_image->list);
441
442         return resource;
443
444         kfree(resource);
445 err_alloc:
446         /* Unlock image */
447         spin_lock(&(master_image->lock));
448         master_image->locked = 0;
449         spin_unlock(&(master_image->lock));
450 err_image:
451 err_bus:
452         return NULL;
453 }
454 EXPORT_SYMBOL(vme_master_request);
455
456 int vme_master_set (struct vme_resource *resource, int enabled,
457         unsigned long long vme_base, unsigned long long size,
458         vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
459 {
460         struct vme_bridge *bridge = find_bridge(resource);
461         struct vme_master_resource *image;
462         int retval;
463
464         if (resource->type != VME_MASTER) {
465                 printk("Not a master resource\n");
466                 return -EINVAL;
467         }
468
469         image = list_entry(resource->entry, struct vme_master_resource, list);
470
471         if (bridge->master_set == NULL) {
472                 printk("vme_master_set not supported\n");
473                 return -EINVAL;
474         }
475
476         if(!(((image->address_attr & aspace) == aspace) &&
477                 ((image->cycle_attr & cycle) == cycle) &&
478                 ((image->width_attr & dwidth) == dwidth))) {
479                 printk("Invalid attributes\n");
480                 return -EINVAL;
481         }
482
483         retval = vme_check_window(aspace, vme_base, size);
484         if(retval)
485                 return retval;
486
487         return bridge->master_set(image, enabled, vme_base, size, aspace,
488                 cycle, dwidth);
489 }
490 EXPORT_SYMBOL(vme_master_set);
491
492 int vme_master_get (struct vme_resource *resource, int *enabled,
493         unsigned long long *vme_base, unsigned long long *size,
494         vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
495 {
496         struct vme_bridge *bridge = find_bridge(resource);
497         struct vme_master_resource *image;
498
499         if (resource->type != VME_MASTER) {
500                 printk("Not a master resource\n");
501                 return -EINVAL;
502         }
503
504         image = list_entry(resource->entry, struct vme_master_resource, list);
505
506         if (bridge->master_get == NULL) {
507                 printk("vme_master_set not supported\n");
508                 return -EINVAL;
509         }
510
511         return bridge->master_get(image, enabled, vme_base, size, aspace,
512                 cycle, dwidth);
513 }
514 EXPORT_SYMBOL(vme_master_get);
515
516 /*
517  * Read data out of VME space into a buffer.
518  */
519 ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count,
520         loff_t offset)
521 {
522         struct vme_bridge *bridge = find_bridge(resource);
523         struct vme_master_resource *image;
524         size_t length;
525
526         if (bridge->master_read == NULL) {
527                 printk("Reading from resource not supported\n");
528                 return -EINVAL;
529         }
530
531         if (resource->type != VME_MASTER) {
532                 printk("Not a master resource\n");
533                 return -EINVAL;
534         }
535
536         image = list_entry(resource->entry, struct vme_master_resource, list);
537
538         length = vme_get_size(resource);
539
540         if (offset > length) {
541                 printk("Invalid Offset\n");
542                 return -EFAULT;
543         }
544
545         if ((offset + count) > length)
546                 count = length - offset;
547
548         return bridge->master_read(image, buf, count, offset);
549
550 }
551 EXPORT_SYMBOL(vme_master_read);
552
553 /*
554  * Write data out to VME space from a buffer.
555  */
556 ssize_t vme_master_write (struct vme_resource *resource, void *buf,
557         size_t count, loff_t offset)
558 {
559         struct vme_bridge *bridge = find_bridge(resource);
560         struct vme_master_resource *image;
561         size_t length;
562
563         if (bridge->master_write == NULL) {
564                 printk("Writing to resource not supported\n");
565                 return -EINVAL;
566         }
567
568         if (resource->type != VME_MASTER) {
569                 printk("Not a master resource\n");
570                 return -EINVAL;
571         }
572
573         image = list_entry(resource->entry, struct vme_master_resource, list);
574
575         length = vme_get_size(resource);
576
577         if (offset > length) {
578                 printk("Invalid Offset\n");
579                 return -EFAULT;
580         }
581
582         if ((offset + count) > length)
583                 count = length - offset;
584
585         return bridge->master_write(image, buf, count, offset);
586 }
587 EXPORT_SYMBOL(vme_master_write);
588
589 /*
590  * Perform RMW cycle to provided location.
591  */
592 unsigned int vme_master_rmw (struct vme_resource *resource, unsigned int mask,
593         unsigned int compare, unsigned int swap, loff_t offset)
594 {
595         struct vme_bridge *bridge = find_bridge(resource);
596         struct vme_master_resource *image;
597
598         if (bridge->master_rmw == NULL) {
599                 printk("Writing to resource not supported\n");
600                 return -EINVAL;
601         }
602
603         if (resource->type != VME_MASTER) {
604                 printk("Not a master resource\n");
605                 return -EINVAL;
606         }
607
608         image = list_entry(resource->entry, struct vme_master_resource, list);
609
610         return bridge->master_rmw(image, mask, compare, swap, offset);
611 }
612 EXPORT_SYMBOL(vme_master_rmw);
613
614 void vme_master_free(struct vme_resource *resource)
615 {
616         struct vme_master_resource *master_image;
617
618         if (resource->type != VME_MASTER) {
619                 printk("Not a master resource\n");
620                 return;
621         }
622
623         master_image = list_entry(resource->entry, struct vme_master_resource,
624                 list);
625         if (master_image == NULL) {
626                 printk("Can't find master resource\n");
627                 return;
628         }
629
630         /* Unlock image */
631         spin_lock(&(master_image->lock));
632         if (master_image->locked == 0)
633                 printk(KERN_ERR "Image is already free\n");
634
635         master_image->locked = 0;
636         spin_unlock(&(master_image->lock));
637
638         /* Free up resource memory */
639         kfree(resource);
640 }
641 EXPORT_SYMBOL(vme_master_free);
642
643 /*
644  * Request a DMA controller with specific attributes, return some unique
645  * identifier.
646  */
647 struct vme_resource *vme_request_dma(struct device *dev)
648 {
649         struct vme_bridge *bridge;
650         struct list_head *dma_pos = NULL;
651         struct vme_dma_resource *allocated_ctrlr = NULL;
652         struct vme_dma_resource *dma_ctrlr = NULL;
653         struct vme_resource *resource = NULL;
654
655         /* XXX Not checking resource attributes */
656         printk(KERN_ERR "No VME resource Attribute tests done\n");
657
658         bridge = dev_to_bridge(dev);
659         if (bridge == NULL) {
660                 printk(KERN_ERR "Can't find VME bus\n");
661                 goto err_bus;
662         }
663
664         /* Loop through DMA resources */
665         list_for_each(dma_pos, &(bridge->dma_resources)) {
666                 dma_ctrlr = list_entry(dma_pos,
667                         struct vme_dma_resource, list);
668
669                 if (dma_ctrlr == NULL) {
670                         printk("Registered NULL DMA resource\n");
671                         continue;
672                 }
673
674                 /* Find an unlocked controller */
675                 mutex_lock(&(dma_ctrlr->mtx));
676                 if(dma_ctrlr->locked == 0) {
677                         dma_ctrlr->locked = 1;
678                         mutex_unlock(&(dma_ctrlr->mtx));
679                         allocated_ctrlr = dma_ctrlr;
680                         break;
681                 }
682                 mutex_unlock(&(dma_ctrlr->mtx));
683         }
684
685         /* Check to see if we found a resource */
686         if (allocated_ctrlr == NULL)
687                 goto err_ctrlr;
688
689         resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
690         if (resource == NULL) {
691                 printk(KERN_WARNING "Unable to allocate resource structure\n");
692                 goto err_alloc;
693         }
694         resource->type = VME_DMA;
695         resource->entry = &(allocated_ctrlr->list);
696
697         return resource;
698
699 err_alloc:
700         /* Unlock image */
701         mutex_lock(&(dma_ctrlr->mtx));
702         dma_ctrlr->locked = 0;
703         mutex_unlock(&(dma_ctrlr->mtx));
704 err_ctrlr:
705 err_bus:
706         return NULL;
707 }
708 EXPORT_SYMBOL(vme_request_dma);
709
710 /*
711  * Start new list
712  */
713 struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource)
714 {
715         struct vme_dma_resource *ctrlr;
716         struct vme_dma_list *dma_list;
717
718         if (resource->type != VME_DMA) {
719                 printk("Not a DMA resource\n");
720                 return NULL;
721         }
722
723         ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
724
725         dma_list = (struct vme_dma_list *)kmalloc(
726                 sizeof(struct vme_dma_list), GFP_KERNEL);
727         if(dma_list == NULL) {
728                 printk("Unable to allocate memory for new dma list\n");
729                 return NULL;
730         }
731         INIT_LIST_HEAD(&(dma_list->entries));
732         dma_list->parent = ctrlr;
733         mutex_init(&(dma_list->mtx));
734
735         return dma_list;
736 }
737 EXPORT_SYMBOL(vme_new_dma_list);
738
739 /*
740  * Create "Pattern" type attributes
741  */
742 struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern,
743         vme_pattern_t type)
744 {
745         struct vme_dma_attr *attributes;
746         struct vme_dma_pattern *pattern_attr;
747
748         attributes = (struct vme_dma_attr *)kmalloc(
749                 sizeof(struct vme_dma_attr), GFP_KERNEL);
750         if(attributes == NULL) {
751                 printk("Unable to allocate memory for attributes structure\n");
752                 goto err_attr;
753         }
754
755         pattern_attr = (struct vme_dma_pattern *)kmalloc(
756                 sizeof(struct vme_dma_pattern), GFP_KERNEL);
757         if(pattern_attr == NULL) {
758                 printk("Unable to allocate memory for pattern attributes\n");
759                 goto err_pat;
760         }
761
762         attributes->type = VME_DMA_PATTERN;
763         attributes->private = (void *)pattern_attr;
764
765         pattern_attr->pattern = pattern;
766         pattern_attr->type = type;
767
768         return attributes;
769
770         kfree(pattern_attr);
771 err_pat:
772         kfree(attributes);
773 err_attr:
774         return NULL;
775 }
776 EXPORT_SYMBOL(vme_dma_pattern_attribute);
777
778 /*
779  * Create "PCI" type attributes
780  */
781 struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address)
782 {
783         struct vme_dma_attr *attributes;
784         struct vme_dma_pci *pci_attr;
785
786         /* XXX Run some sanity checks here */
787
788         attributes = (struct vme_dma_attr *)kmalloc(
789                 sizeof(struct vme_dma_attr), GFP_KERNEL);
790         if(attributes == NULL) {
791                 printk("Unable to allocate memory for attributes structure\n");
792                 goto err_attr;
793         }
794
795         pci_attr = (struct vme_dma_pci *)kmalloc(sizeof(struct vme_dma_pci),
796                 GFP_KERNEL);
797         if(pci_attr == NULL) {
798                 printk("Unable to allocate memory for pci attributes\n");
799                 goto err_pci;
800         }
801
802
803
804         attributes->type = VME_DMA_PCI;
805         attributes->private = (void *)pci_attr;
806
807         pci_attr->address = address;
808
809         return attributes;
810
811         kfree(pci_attr);
812 err_pci:
813         kfree(attributes);
814 err_attr:
815         return NULL;
816 }
817 EXPORT_SYMBOL(vme_dma_pci_attribute);
818
819 /*
820  * Create "VME" type attributes
821  */
822 struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address,
823         vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
824 {
825         struct vme_dma_attr *attributes;
826         struct vme_dma_vme *vme_attr;
827
828         /* XXX Run some sanity checks here */
829
830         attributes = (struct vme_dma_attr *)kmalloc(
831                 sizeof(struct vme_dma_attr), GFP_KERNEL);
832         if(attributes == NULL) {
833                 printk("Unable to allocate memory for attributes structure\n");
834                 goto err_attr;
835         }
836
837         vme_attr = (struct vme_dma_vme *)kmalloc(sizeof(struct vme_dma_vme),
838                 GFP_KERNEL);
839         if(vme_attr == NULL) {
840                 printk("Unable to allocate memory for vme attributes\n");
841                 goto err_vme;
842         }
843
844         attributes->type = VME_DMA_VME;
845         attributes->private = (void *)vme_attr;
846
847         vme_attr->address = address;
848         vme_attr->aspace = aspace;
849         vme_attr->cycle = cycle;
850         vme_attr->dwidth = dwidth;
851
852         return attributes;
853
854         kfree(vme_attr);
855 err_vme:
856         kfree(attributes);
857 err_attr:
858         return NULL;
859 }
860 EXPORT_SYMBOL(vme_dma_vme_attribute);
861
862 /*
863  * Free attribute
864  */
865 void vme_dma_free_attribute(struct vme_dma_attr *attributes)
866 {
867         kfree(attributes->private);
868         kfree(attributes);
869 }
870 EXPORT_SYMBOL(vme_dma_free_attribute);
871
872 int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
873         struct vme_dma_attr *dest, size_t count)
874 {
875         struct vme_bridge *bridge = list->parent->parent;
876         int retval;
877
878         if (bridge->dma_list_add == NULL) {
879                 printk("Link List DMA generation not supported\n");
880                 return -EINVAL;
881         }
882
883         if (mutex_trylock(&(list->mtx))) {
884                 printk("Link List already submitted\n");
885                 return -EINVAL;
886         }
887
888         retval = bridge->dma_list_add(list, src, dest, count);
889
890         mutex_unlock(&(list->mtx));
891
892         return retval;
893 }
894 EXPORT_SYMBOL(vme_dma_list_add);
895
896 int vme_dma_list_exec(struct vme_dma_list *list)
897 {
898         struct vme_bridge *bridge = list->parent->parent;
899         int retval;
900
901         if (bridge->dma_list_exec == NULL) {
902                 printk("Link List DMA execution not supported\n");
903                 return -EINVAL;
904         }
905
906         mutex_lock(&(list->mtx));
907
908         retval = bridge->dma_list_exec(list);
909
910         mutex_unlock(&(list->mtx));
911
912         return retval;
913 }
914 EXPORT_SYMBOL(vme_dma_list_exec);
915
916 int vme_dma_list_free(struct vme_dma_list *list)
917 {
918         struct vme_bridge *bridge = list->parent->parent;
919         int retval;
920
921         if (bridge->dma_list_empty == NULL) {
922                 printk("Emptying of Link Lists not supported\n");
923                 return -EINVAL;
924         }
925
926         if (mutex_trylock(&(list->mtx))) {
927                 printk("Link List in use\n");
928                 return -EINVAL;
929         }
930
931         /*
932          * Empty out all of the entries from the dma list. We need to go to the
933          * low level driver as dma entries are driver specific.
934          */
935         retval = bridge->dma_list_empty(list);
936         if (retval) {
937                 printk("Unable to empty link-list entries\n");
938                 mutex_unlock(&(list->mtx));
939                 return retval;
940         }
941         mutex_unlock(&(list->mtx));
942         kfree(list);
943
944         return retval;
945 }
946 EXPORT_SYMBOL(vme_dma_list_free);
947
948 int vme_dma_free(struct vme_resource *resource)
949 {
950         struct vme_dma_resource *ctrlr;
951
952         if (resource->type != VME_DMA) {
953                 printk("Not a DMA resource\n");
954                 return -EINVAL;
955         }
956
957         ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
958
959         if (mutex_trylock(&(ctrlr->mtx))) {
960                 printk("Resource busy, can't free\n");
961                 return -EBUSY;
962         }
963
964         if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) {
965                 printk("Resource still processing transfers\n");
966                 mutex_unlock(&(ctrlr->mtx));
967                 return -EBUSY;
968         }
969
970         ctrlr->locked = 0;
971
972         mutex_unlock(&(ctrlr->mtx));
973
974         return 0;
975 }
976 EXPORT_SYMBOL(vme_dma_free);
977
978 int vme_request_irq(struct device *dev, int level, int statid,
979         void (*callback)(int level, int vector, void *priv_data),
980         void *priv_data)
981 {
982         struct vme_bridge *bridge;
983
984         bridge = dev_to_bridge(dev);
985         if (bridge == NULL) {
986                 printk(KERN_ERR "Can't find VME bus\n");
987                 return -EINVAL;
988         }
989
990         if((level < 1) || (level > 7)) {
991                 printk(KERN_WARNING "Invalid interrupt level\n");
992                 return -EINVAL;
993         }
994
995         if (bridge->request_irq == NULL) {
996                 printk("Registering interrupts not supported\n");
997                 return -EINVAL;
998         }
999
1000         return bridge->request_irq(level, statid, callback, priv_data);
1001 }
1002 EXPORT_SYMBOL(vme_request_irq);
1003
1004 void vme_free_irq(struct device *dev, int level, int statid)
1005 {
1006         struct vme_bridge *bridge;
1007
1008         bridge = dev_to_bridge(dev);
1009         if (bridge == NULL) {
1010                 printk(KERN_ERR "Can't find VME bus\n");
1011                 return;
1012         }
1013
1014         if((level < 1) || (level > 7)) {
1015                 printk(KERN_WARNING "Invalid interrupt level\n");
1016                 return;
1017         }
1018
1019         if (bridge->free_irq == NULL) {
1020                 printk("Freeing interrupts not supported\n");
1021                 return;
1022         }
1023
1024         bridge->free_irq(level, statid);
1025 }
1026 EXPORT_SYMBOL(vme_free_irq);
1027
1028 int vme_generate_irq(struct device *dev, int level, int statid)
1029 {
1030         struct vme_bridge *bridge;
1031
1032         bridge = dev_to_bridge(dev);
1033         if (bridge == NULL) {
1034                 printk(KERN_ERR "Can't find VME bus\n");
1035                 return -EINVAL;
1036         }
1037
1038         if((level < 1) || (level > 7)) {
1039                 printk(KERN_WARNING "Invalid interrupt level\n");
1040                 return -EINVAL;
1041         }
1042
1043         if (bridge->generate_irq == NULL) {
1044                 printk("Interrupt generation not supported\n");
1045                 return -EINVAL;
1046         }
1047
1048         return bridge->generate_irq(level, statid);
1049 }
1050 EXPORT_SYMBOL(vme_generate_irq);
1051
1052 /*
1053  * Request the location monitor, return resource or NULL
1054  */
1055 struct vme_resource *vme_lm_request(struct device *dev)
1056 {
1057         struct vme_bridge *bridge;
1058         struct list_head *lm_pos = NULL;
1059         struct vme_lm_resource *allocated_lm = NULL;
1060         struct vme_lm_resource *lm = NULL;
1061         struct vme_resource *resource = NULL;
1062
1063         bridge = dev_to_bridge(dev);
1064         if (bridge == NULL) {
1065                 printk(KERN_ERR "Can't find VME bus\n");
1066                 goto err_bus;
1067         }
1068
1069         /* Loop through DMA resources */
1070         list_for_each(lm_pos, &(bridge->lm_resources)) {
1071                 lm = list_entry(lm_pos,
1072                         struct vme_lm_resource, list);
1073
1074                 if (lm == NULL) {
1075                         printk(KERN_ERR "Registered NULL Location Monitor "
1076                                 "resource\n");
1077                         continue;
1078                 }
1079
1080                 /* Find an unlocked controller */
1081                 mutex_lock(&(lm->mtx));
1082                 if (lm->locked == 0) {
1083                         lm->locked = 1;
1084                         mutex_unlock(&(lm->mtx));
1085                         allocated_lm = lm;
1086                         break;
1087                 }
1088                 mutex_unlock(&(lm->mtx));
1089         }
1090
1091         /* Check to see if we found a resource */
1092         if (allocated_lm == NULL)
1093                 goto err_lm;
1094
1095         resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
1096         if (resource == NULL) {
1097                 printk(KERN_ERR "Unable to allocate resource structure\n");
1098                 goto err_alloc;
1099         }
1100         resource->type = VME_LM;
1101         resource->entry = &(allocated_lm->list);
1102
1103         return resource;
1104
1105 err_alloc:
1106         /* Unlock image */
1107         mutex_lock(&(lm->mtx));
1108         lm->locked = 0;
1109         mutex_unlock(&(lm->mtx));
1110 err_lm:
1111 err_bus:
1112         return NULL;
1113 }
1114 EXPORT_SYMBOL(vme_lm_request);
1115
1116 int vme_lm_count(struct vme_resource *resource)
1117 {
1118         struct vme_lm_resource *lm;
1119
1120         if (resource->type != VME_LM) {
1121                 printk(KERN_ERR "Not a Location Monitor resource\n");
1122                 return -EINVAL;
1123         }
1124
1125         lm = list_entry(resource->entry, struct vme_lm_resource, list);
1126
1127         return lm->monitors;
1128 }
1129 EXPORT_SYMBOL(vme_lm_count);
1130
1131 int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base,
1132         vme_address_t aspace, vme_cycle_t cycle)
1133 {
1134         struct vme_bridge *bridge = find_bridge(resource);
1135         struct vme_lm_resource *lm;
1136
1137         if (resource->type != VME_LM) {
1138                 printk(KERN_ERR "Not a Location Monitor resource\n");
1139                 return -EINVAL;
1140         }
1141
1142         lm = list_entry(resource->entry, struct vme_lm_resource, list);
1143
1144         if (bridge->lm_set == NULL) {
1145                 printk(KERN_ERR "vme_lm_set not supported\n");
1146                 return -EINVAL;
1147         }
1148
1149         /* XXX Check parameters */
1150
1151         return lm->parent->lm_set(lm, lm_base, aspace, cycle);
1152 }
1153 EXPORT_SYMBOL(vme_lm_set);
1154
1155 int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base,
1156         vme_address_t *aspace, vme_cycle_t *cycle)
1157 {
1158         struct vme_bridge *bridge = find_bridge(resource);
1159         struct vme_lm_resource *lm;
1160
1161         if (resource->type != VME_LM) {
1162                 printk(KERN_ERR "Not a Location Monitor resource\n");
1163                 return -EINVAL;
1164         }
1165
1166         lm = list_entry(resource->entry, struct vme_lm_resource, list);
1167
1168         if (bridge->lm_get == NULL) {
1169                 printk(KERN_ERR "vme_lm_get not supported\n");
1170                 return -EINVAL;
1171         }
1172
1173         return bridge->lm_get(lm, lm_base, aspace, cycle);
1174 }
1175 EXPORT_SYMBOL(vme_lm_get);
1176
1177 int vme_lm_attach(struct vme_resource *resource, int monitor,
1178         void (*callback)(int))
1179 {
1180         struct vme_bridge *bridge = find_bridge(resource);
1181         struct vme_lm_resource *lm;
1182
1183         if (resource->type != VME_LM) {
1184                 printk(KERN_ERR "Not a Location Monitor resource\n");
1185                 return -EINVAL;
1186         }
1187
1188         lm = list_entry(resource->entry, struct vme_lm_resource, list);
1189
1190         if (bridge->lm_attach == NULL) {
1191                 printk(KERN_ERR "vme_lm_attach not supported\n");
1192                 return -EINVAL;
1193         }
1194
1195         return bridge->lm_attach(lm, monitor, callback);
1196 }
1197 EXPORT_SYMBOL(vme_lm_attach);
1198
1199 int vme_lm_detach(struct vme_resource *resource, int monitor)
1200 {
1201         struct vme_bridge *bridge = find_bridge(resource);
1202         struct vme_lm_resource *lm;
1203
1204         if (resource->type != VME_LM) {
1205                 printk(KERN_ERR "Not a Location Monitor resource\n");
1206                 return -EINVAL;
1207         }
1208
1209         lm = list_entry(resource->entry, struct vme_lm_resource, list);
1210
1211         if (bridge->lm_detach == NULL) {
1212                 printk(KERN_ERR "vme_lm_detach not supported\n");
1213                 return -EINVAL;
1214         }
1215
1216         return bridge->lm_detach(lm, monitor);
1217 }
1218 EXPORT_SYMBOL(vme_lm_detach);
1219
1220 void vme_lm_free(struct vme_resource *resource)
1221 {
1222         struct vme_lm_resource *lm;
1223
1224         if (resource->type != VME_LM) {
1225                 printk(KERN_ERR "Not a Location Monitor resource\n");
1226                 return;
1227         }
1228
1229         lm = list_entry(resource->entry, struct vme_lm_resource, list);
1230
1231         if (mutex_trylock(&(lm->mtx))) {
1232                 printk(KERN_ERR "Resource busy, can't free\n");
1233                 return;
1234         }
1235
1236         /* XXX Check to see that there aren't any callbacks still attached */
1237
1238         lm->locked = 0;
1239
1240         mutex_unlock(&(lm->mtx));
1241 }
1242 EXPORT_SYMBOL(vme_lm_free);
1243
1244 int vme_slot_get(struct device *bus)
1245 {
1246         struct vme_bridge *bridge;
1247
1248         bridge = dev_to_bridge(bus);
1249         if (bridge == NULL) {
1250                 printk(KERN_ERR "Can't find VME bus\n");
1251                 return -EINVAL;
1252         }
1253
1254         if (bridge->slot_get == NULL) {
1255                 printk("vme_slot_get not supported\n");
1256                 return -EINVAL;
1257         }
1258
1259         return bridge->slot_get();
1260 }
1261 EXPORT_SYMBOL(vme_slot_get);
1262
1263
1264 /* - Bridge Registration --------------------------------------------------- */
1265
1266 static int vme_alloc_bus_num(void)
1267 {
1268         int i;
1269
1270         mutex_lock(&vme_bus_num_mtx);
1271         for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) {
1272                 if (((vme_bus_numbers >> i) & 0x1) == 0) {
1273                         vme_bus_numbers |= (0x1 << i);
1274                         break;
1275                 }
1276         }
1277         mutex_unlock(&vme_bus_num_mtx);
1278
1279         return i;
1280 }
1281
1282 static void vme_free_bus_num(int bus)
1283 {
1284         mutex_lock(&vme_bus_num_mtx);
1285         vme_bus_numbers |= ~(0x1 << bus);
1286         mutex_unlock(&vme_bus_num_mtx);
1287 }
1288
1289 int vme_register_bridge (struct vme_bridge *bridge)
1290 {
1291         struct device *dev;
1292         int retval;
1293         int i;
1294
1295         bridge->num = vme_alloc_bus_num();
1296
1297         /* This creates 32 vme "slot" devices. This equates to a slot for each
1298          * ID available in a system conforming to the ANSI/VITA 1-1994
1299          * specification.
1300          */
1301         for (i = 0; i < VME_SLOTS_MAX; i++) {
1302                 dev = &(bridge->dev[i]);
1303                 memset(dev, 0, sizeof(struct device));
1304
1305                 dev->parent = bridge->parent;
1306                 dev->bus = &(vme_bus_type);
1307                 /*
1308                  * We save a pointer to the bridge in platform_data so that we
1309                  * can get to it later. We keep driver_data for use by the
1310                  * driver that binds against the slot
1311                  */
1312                 dev->platform_data = bridge;
1313                 dev_set_name(dev, "vme-%x.%x", bridge->num, i + 1);
1314
1315                 retval = device_register(dev);
1316                 if(retval)
1317                         goto err_reg;
1318         }
1319
1320         return retval;
1321
1322         i = VME_SLOTS_MAX;
1323 err_reg:
1324         while (i > -1) {
1325                 dev = &(bridge->dev[i]);
1326                 device_unregister(dev);
1327         }
1328         vme_free_bus_num(bridge->num);
1329         return retval;
1330 }
1331 EXPORT_SYMBOL(vme_register_bridge);
1332
1333 void vme_unregister_bridge (struct vme_bridge *bridge)
1334 {
1335         int i;
1336         struct device *dev;
1337
1338
1339         for (i = 0; i < VME_SLOTS_MAX; i++) {
1340                 dev = &(bridge->dev[i]);
1341                 device_unregister(dev);
1342         }
1343         vme_free_bus_num(bridge->num);
1344 }
1345 EXPORT_SYMBOL(vme_unregister_bridge);
1346
1347
1348 /* - Driver Registration --------------------------------------------------- */
1349
1350 int vme_register_driver (struct vme_driver *drv)
1351 {
1352         drv->driver.name = drv->name;
1353         drv->driver.bus = &vme_bus_type;
1354
1355         return driver_register(&drv->driver);
1356 }
1357 EXPORT_SYMBOL(vme_register_driver);
1358
1359 void vme_unregister_driver (struct vme_driver *drv)
1360 {
1361         driver_unregister(&drv->driver);
1362 }
1363 EXPORT_SYMBOL(vme_unregister_driver);
1364
1365 /* - Bus Registration ------------------------------------------------------ */
1366
1367 int vme_calc_slot(struct device *dev)
1368 {
1369         struct vme_bridge *bridge;
1370         int num;
1371
1372         bridge = dev_to_bridge(dev);
1373
1374         /* Determine slot number */
1375         num = 0;
1376         while(num < VME_SLOTS_MAX) {
1377                 if(&(bridge->dev[num]) == dev) {
1378                         break;
1379                 }
1380                 num++;
1381         }
1382         if (num == VME_SLOTS_MAX) {
1383                 dev_err(dev, "Failed to identify slot\n");
1384                 num = 0;
1385                 goto err_dev;
1386         }
1387         num++;
1388
1389 err_dev:
1390         return num;
1391 }
1392
1393 static struct vme_driver *dev_to_vme_driver(struct device *dev)
1394 {
1395         if(dev->driver == NULL)
1396                 printk("Bugger dev->driver is NULL\n");
1397
1398         return container_of(dev->driver, struct vme_driver, driver);
1399 }
1400
1401 static int vme_bus_match(struct device *dev, struct device_driver *drv)
1402 {
1403         struct vme_bridge *bridge;
1404         struct vme_driver *driver;
1405         int i, num;
1406
1407         bridge = dev_to_bridge(dev);
1408         driver = container_of(drv, struct vme_driver, driver);
1409
1410         num = vme_calc_slot(dev);
1411         if (!num)
1412                 goto err_dev;
1413
1414         if (driver->bind_table == NULL) {
1415                 dev_err(dev, "Bind table NULL\n");
1416                 goto err_table;
1417         }
1418
1419         i = 0;
1420         while((driver->bind_table[i].bus != 0) ||
1421                 (driver->bind_table[i].slot != 0)) {
1422
1423                 if (bridge->num == driver->bind_table[i].bus) {
1424                         if (num == driver->bind_table[i].slot)
1425                                 return 1;
1426
1427                         if (driver->bind_table[i].slot == VME_SLOT_ALL)
1428                                 return 1;
1429
1430                         if ((driver->bind_table[i].slot == VME_SLOT_CURRENT) &&
1431                                 (num == vme_slot_get(dev)))
1432                                 return 1;
1433                 }
1434                 i++;
1435         }
1436
1437 err_dev:
1438 err_table:
1439         return 0;
1440 }
1441
1442 static int vme_bus_probe(struct device *dev)
1443 {
1444         struct vme_bridge *bridge;
1445         struct vme_driver *driver;
1446         int retval = -ENODEV;
1447
1448         driver = dev_to_vme_driver(dev);
1449         bridge = dev_to_bridge(dev);
1450
1451         if(driver->probe != NULL) {
1452                 retval = driver->probe(dev, bridge->num, vme_calc_slot(dev));
1453         }
1454
1455         return retval;
1456 }
1457
1458 static int vme_bus_remove(struct device *dev)
1459 {
1460         struct vme_bridge *bridge;
1461         struct vme_driver *driver;
1462         int retval = -ENODEV;
1463
1464         driver = dev_to_vme_driver(dev);
1465         bridge = dev_to_bridge(dev);
1466
1467         if(driver->remove != NULL) {
1468                 retval = driver->remove(dev, bridge->num, vme_calc_slot(dev));
1469         }
1470
1471         return retval;
1472 }
1473
1474 struct bus_type vme_bus_type = {
1475         .name = "vme",
1476         .match = vme_bus_match,
1477         .probe = vme_bus_probe,
1478         .remove = vme_bus_remove,
1479 };
1480 EXPORT_SYMBOL(vme_bus_type);
1481
1482 static int __init vme_init (void)
1483 {
1484         return bus_register(&vme_bus_type);
1485 }
1486
1487 static void __exit vme_exit (void)
1488 {
1489         bus_unregister(&vme_bus_type);
1490 }
1491
1492 MODULE_DESCRIPTION("VME bridge driver framework");
1493 MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
1494 MODULE_LICENSE("GPL");
1495
1496 module_init(vme_init);
1497 module_exit(vme_exit);