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