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