Merge remote-tracking branch 'char-misc/char-misc-next'
[deliverable/linux.git] / drivers / vme / vme.c
CommitLineData
a17a75e2
MW
1/*
2 * VME Bridge Framework
3 *
66bd8db5
MW
4 * Author: Martyn Welch <martyn.welch@ge.com>
5 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
a17a75e2
MW
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
050c3d52
PG
16#include <linux/init.h>
17#include <linux/export.h>
a17a75e2
MW
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>
400822fe 30#include <linux/mutex.h>
a17a75e2 31#include <linux/spinlock.h>
5a0e3ad6 32#include <linux/slab.h>
db3b9e99 33#include <linux/vme.h>
a17a75e2 34
a17a75e2
MW
35#include "vme_bridge.h"
36
733e3ef0 37/* Bitmask and list of registered buses both protected by common mutex */
a17a75e2 38static unsigned int vme_bus_numbers;
733e3ef0
MV
39static LIST_HEAD(vme_bus_list);
40static DEFINE_MUTEX(vme_buses_lock);
a17a75e2 41
ead1f3e3 42static int __init vme_init(void);
a17a75e2 43
8f966dc4 44static struct vme_dev *dev_to_vme_dev(struct device *dev)
a17a75e2 45{
8f966dc4 46 return container_of(dev, struct vme_dev, dev);
a17a75e2
MW
47}
48
49/*
50 * Find the bridge that the resource is associated with.
51 */
52static struct vme_bridge *find_bridge(struct vme_resource *resource)
53{
54 /* Get list to search */
55 switch (resource->type) {
56 case VME_MASTER:
57 return list_entry(resource->entry, struct vme_master_resource,
58 list)->parent;
59 break;
60 case VME_SLAVE:
61 return list_entry(resource->entry, struct vme_slave_resource,
62 list)->parent;
63 break;
64 case VME_DMA:
65 return list_entry(resource->entry, struct vme_dma_resource,
66 list)->parent;
67 break;
42fb5031
MW
68 case VME_LM:
69 return list_entry(resource->entry, struct vme_lm_resource,
70 list)->parent;
71 break;
a17a75e2
MW
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.
a17a75e2 82 */
ead1f3e3 83void *vme_alloc_consistent(struct vme_resource *resource, size_t size,
a17a75e2
MW
84 dma_addr_t *dma)
85{
86 struct vme_bridge *bridge;
a17a75e2 87
ead1f3e3
MW
88 if (resource == NULL) {
89 printk(KERN_ERR "No resource\n");
a17a75e2
MW
90 return NULL;
91 }
92
93 bridge = find_bridge(resource);
ead1f3e3
MW
94 if (bridge == NULL) {
95 printk(KERN_ERR "Can't find bridge\n");
a17a75e2
MW
96 return NULL;
97 }
98
a17a75e2 99 if (bridge->parent == NULL) {
25958ce3 100 printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name);
7f58f025
MV
101 return NULL;
102 }
103
104 if (bridge->alloc_consistent == NULL) {
25958ce3
GKH
105 printk(KERN_ERR "alloc_consistent not supported by bridge %s\n",
106 bridge->name);
a17a75e2
MW
107 return NULL;
108 }
a17a75e2 109
7f58f025 110 return bridge->alloc_consistent(bridge->parent, size, dma);
a17a75e2
MW
111}
112EXPORT_SYMBOL(vme_alloc_consistent);
113
114/*
115 * Free previously allocated contiguous block of memory.
a17a75e2
MW
116 */
117void vme_free_consistent(struct vme_resource *resource, size_t size,
118 void *vaddr, dma_addr_t dma)
119{
120 struct vme_bridge *bridge;
a17a75e2 121
ead1f3e3
MW
122 if (resource == NULL) {
123 printk(KERN_ERR "No resource\n");
a17a75e2
MW
124 return;
125 }
126
127 bridge = find_bridge(resource);
ead1f3e3
MW
128 if (bridge == NULL) {
129 printk(KERN_ERR "Can't find bridge\n");
a17a75e2
MW
130 return;
131 }
132
7f58f025 133 if (bridge->parent == NULL) {
25958ce3 134 printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name);
7f58f025
MV
135 return;
136 }
137
138 if (bridge->free_consistent == NULL) {
25958ce3
GKH
139 printk(KERN_ERR "free_consistent not supported by bridge %s\n",
140 bridge->name);
7f58f025
MV
141 return;
142 }
a17a75e2 143
7f58f025 144 bridge->free_consistent(bridge->parent, size, vaddr, dma);
a17a75e2
MW
145}
146EXPORT_SYMBOL(vme_free_consistent);
147
148size_t vme_get_size(struct vme_resource *resource)
149{
150 int enabled, retval;
151 unsigned long long base, size;
152 dma_addr_t buf_base;
6af04b06 153 u32 aspace, cycle, dwidth;
a17a75e2
MW
154
155 switch (resource->type) {
156 case VME_MASTER:
157 retval = vme_master_get(resource, &enabled, &base, &size,
158 &aspace, &cycle, &dwidth);
159
160 return size;
161 break;
162 case VME_SLAVE:
163 retval = vme_slave_get(resource, &enabled, &base, &size,
164 &buf_base, &aspace, &cycle);
165
166 return size;
167 break;
168 case VME_DMA:
169 return 0;
170 break;
171 default:
172 printk(KERN_ERR "Unknown resource type\n");
173 return 0;
174 break;
175 }
176}
177EXPORT_SYMBOL(vme_get_size);
178
ef73f886
DK
179int vme_check_window(u32 aspace, unsigned long long vme_base,
180 unsigned long long size)
a17a75e2
MW
181{
182 int retval = 0;
183
184 switch (aspace) {
185 case VME_A16:
186 if (((vme_base + size) > VME_A16_MAX) ||
187 (vme_base > VME_A16_MAX))
188 retval = -EFAULT;
189 break;
190 case VME_A24:
191 if (((vme_base + size) > VME_A24_MAX) ||
192 (vme_base > VME_A24_MAX))
193 retval = -EFAULT;
194 break;
195 case VME_A32:
196 if (((vme_base + size) > VME_A32_MAX) ||
197 (vme_base > VME_A32_MAX))
198 retval = -EFAULT;
199 break;
200 case VME_A64:
e7fd80cb
DK
201 if ((size != 0) && (vme_base > U64_MAX + 1 - size))
202 retval = -EFAULT;
a17a75e2
MW
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:
ead1f3e3 216 printk(KERN_ERR "Invalid address space\n");
a17a75e2
MW
217 retval = -EINVAL;
218 break;
219 }
220
221 return retval;
222}
ef73f886 223EXPORT_SYMBOL(vme_check_window);
a17a75e2 224
472f16f3
DK
225static u32 vme_get_aspace(int am)
226{
227 switch (am) {
228 case 0x29:
229 case 0x2D:
230 return VME_A16;
231 case 0x38:
232 case 0x39:
233 case 0x3A:
234 case 0x3B:
235 case 0x3C:
236 case 0x3D:
237 case 0x3E:
238 case 0x3F:
239 return VME_A24;
240 case 0x8:
241 case 0x9:
242 case 0xA:
243 case 0xB:
244 case 0xC:
245 case 0xD:
246 case 0xE:
247 case 0xF:
248 return VME_A32;
249 case 0x0:
250 case 0x1:
251 case 0x3:
252 return VME_A64;
253 }
254
255 return 0;
256}
257
a17a75e2
MW
258/*
259 * Request a slave image with specific attributes, return some unique
260 * identifier.
261 */
6af04b06
MW
262struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address,
263 u32 cycle)
a17a75e2
MW
264{
265 struct vme_bridge *bridge;
266 struct list_head *slave_pos = NULL;
267 struct vme_slave_resource *allocated_image = NULL;
268 struct vme_slave_resource *slave_image = NULL;
269 struct vme_resource *resource = NULL;
270
8f966dc4 271 bridge = vdev->bridge;
a17a75e2
MW
272 if (bridge == NULL) {
273 printk(KERN_ERR "Can't find VME bus\n");
274 goto err_bus;
275 }
276
277 /* Loop through slave resources */
886953e9 278 list_for_each(slave_pos, &bridge->slave_resources) {
a17a75e2
MW
279 slave_image = list_entry(slave_pos,
280 struct vme_slave_resource, list);
281
282 if (slave_image == NULL) {
ead1f3e3 283 printk(KERN_ERR "Registered NULL Slave resource\n");
a17a75e2
MW
284 continue;
285 }
286
287 /* Find an unlocked and compatible image */
886953e9 288 mutex_lock(&slave_image->mtx);
ead1f3e3 289 if (((slave_image->address_attr & address) == address) &&
a17a75e2
MW
290 ((slave_image->cycle_attr & cycle) == cycle) &&
291 (slave_image->locked == 0)) {
292
293 slave_image->locked = 1;
886953e9 294 mutex_unlock(&slave_image->mtx);
a17a75e2
MW
295 allocated_image = slave_image;
296 break;
297 }
886953e9 298 mutex_unlock(&slave_image->mtx);
a17a75e2
MW
299 }
300
301 /* No free image */
302 if (allocated_image == NULL)
303 goto err_image;
304
305 resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
306 if (resource == NULL) {
307 printk(KERN_WARNING "Unable to allocate resource structure\n");
308 goto err_alloc;
309 }
310 resource->type = VME_SLAVE;
886953e9 311 resource->entry = &allocated_image->list;
a17a75e2
MW
312
313 return resource;
314
315err_alloc:
316 /* Unlock image */
886953e9 317 mutex_lock(&slave_image->mtx);
a17a75e2 318 slave_image->locked = 0;
886953e9 319 mutex_unlock(&slave_image->mtx);
a17a75e2
MW
320err_image:
321err_bus:
322 return NULL;
323}
324EXPORT_SYMBOL(vme_slave_request);
325
ead1f3e3 326int vme_slave_set(struct vme_resource *resource, int enabled,
a17a75e2 327 unsigned long long vme_base, unsigned long long size,
6af04b06 328 dma_addr_t buf_base, u32 aspace, u32 cycle)
a17a75e2
MW
329{
330 struct vme_bridge *bridge = find_bridge(resource);
331 struct vme_slave_resource *image;
332 int retval;
333
334 if (resource->type != VME_SLAVE) {
ead1f3e3 335 printk(KERN_ERR "Not a slave resource\n");
a17a75e2
MW
336 return -EINVAL;
337 }
338
339 image = list_entry(resource->entry, struct vme_slave_resource, list);
340
341 if (bridge->slave_set == NULL) {
ead1f3e3 342 printk(KERN_ERR "Function not supported\n");
a17a75e2
MW
343 return -ENOSYS;
344 }
345
ead1f3e3 346 if (!(((image->address_attr & aspace) == aspace) &&
a17a75e2 347 ((image->cycle_attr & cycle) == cycle))) {
ead1f3e3 348 printk(KERN_ERR "Invalid attributes\n");
a17a75e2
MW
349 return -EINVAL;
350 }
351
352 retval = vme_check_window(aspace, vme_base, size);
ead1f3e3 353 if (retval)
a17a75e2
MW
354 return retval;
355
356 return bridge->slave_set(image, enabled, vme_base, size, buf_base,
357 aspace, cycle);
358}
359EXPORT_SYMBOL(vme_slave_set);
360
ead1f3e3 361int vme_slave_get(struct vme_resource *resource, int *enabled,
a17a75e2 362 unsigned long long *vme_base, unsigned long long *size,
6af04b06 363 dma_addr_t *buf_base, u32 *aspace, u32 *cycle)
a17a75e2
MW
364{
365 struct vme_bridge *bridge = find_bridge(resource);
366 struct vme_slave_resource *image;
367
368 if (resource->type != VME_SLAVE) {
ead1f3e3 369 printk(KERN_ERR "Not a slave resource\n");
a17a75e2
MW
370 return -EINVAL;
371 }
372
373 image = list_entry(resource->entry, struct vme_slave_resource, list);
374
51a569f7 375 if (bridge->slave_get == NULL) {
ead1f3e3 376 printk(KERN_ERR "vme_slave_get not supported\n");
a17a75e2
MW
377 return -EINVAL;
378 }
379
380 return bridge->slave_get(image, enabled, vme_base, size, buf_base,
381 aspace, cycle);
382}
383EXPORT_SYMBOL(vme_slave_get);
384
385void vme_slave_free(struct vme_resource *resource)
386{
387 struct vme_slave_resource *slave_image;
388
389 if (resource->type != VME_SLAVE) {
ead1f3e3 390 printk(KERN_ERR "Not a slave resource\n");
a17a75e2
MW
391 return;
392 }
393
394 slave_image = list_entry(resource->entry, struct vme_slave_resource,
395 list);
396 if (slave_image == NULL) {
ead1f3e3 397 printk(KERN_ERR "Can't find slave resource\n");
a17a75e2
MW
398 return;
399 }
400
401 /* Unlock image */
886953e9 402 mutex_lock(&slave_image->mtx);
a17a75e2
MW
403 if (slave_image->locked == 0)
404 printk(KERN_ERR "Image is already free\n");
405
406 slave_image->locked = 0;
886953e9 407 mutex_unlock(&slave_image->mtx);
a17a75e2
MW
408
409 /* Free up resource memory */
410 kfree(resource);
411}
412EXPORT_SYMBOL(vme_slave_free);
413
414/*
415 * Request a master image with specific attributes, return some unique
416 * identifier.
417 */
6af04b06
MW
418struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address,
419 u32 cycle, u32 dwidth)
a17a75e2
MW
420{
421 struct vme_bridge *bridge;
422 struct list_head *master_pos = NULL;
423 struct vme_master_resource *allocated_image = NULL;
424 struct vme_master_resource *master_image = NULL;
425 struct vme_resource *resource = NULL;
426
8f966dc4 427 bridge = vdev->bridge;
a17a75e2
MW
428 if (bridge == NULL) {
429 printk(KERN_ERR "Can't find VME bus\n");
430 goto err_bus;
431 }
432
433 /* Loop through master resources */
886953e9 434 list_for_each(master_pos, &bridge->master_resources) {
a17a75e2
MW
435 master_image = list_entry(master_pos,
436 struct vme_master_resource, list);
437
438 if (master_image == NULL) {
439 printk(KERN_WARNING "Registered NULL master resource\n");
440 continue;
441 }
442
443 /* Find an unlocked and compatible image */
886953e9 444 spin_lock(&master_image->lock);
ead1f3e3 445 if (((master_image->address_attr & address) == address) &&
a17a75e2
MW
446 ((master_image->cycle_attr & cycle) == cycle) &&
447 ((master_image->width_attr & dwidth) == dwidth) &&
448 (master_image->locked == 0)) {
449
450 master_image->locked = 1;
886953e9 451 spin_unlock(&master_image->lock);
a17a75e2
MW
452 allocated_image = master_image;
453 break;
454 }
886953e9 455 spin_unlock(&master_image->lock);
a17a75e2
MW
456 }
457
458 /* Check to see if we found a resource */
459 if (allocated_image == NULL) {
460 printk(KERN_ERR "Can't find a suitable resource\n");
461 goto err_image;
462 }
463
464 resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
465 if (resource == NULL) {
466 printk(KERN_ERR "Unable to allocate resource structure\n");
467 goto err_alloc;
468 }
469 resource->type = VME_MASTER;
886953e9 470 resource->entry = &allocated_image->list;
a17a75e2
MW
471
472 return resource;
473
a17a75e2
MW
474err_alloc:
475 /* Unlock image */
886953e9 476 spin_lock(&master_image->lock);
a17a75e2 477 master_image->locked = 0;
886953e9 478 spin_unlock(&master_image->lock);
a17a75e2
MW
479err_image:
480err_bus:
481 return NULL;
482}
483EXPORT_SYMBOL(vme_master_request);
484
ead1f3e3 485int vme_master_set(struct vme_resource *resource, int enabled,
6af04b06
MW
486 unsigned long long vme_base, unsigned long long size, u32 aspace,
487 u32 cycle, u32 dwidth)
a17a75e2
MW
488{
489 struct vme_bridge *bridge = find_bridge(resource);
490 struct vme_master_resource *image;
491 int retval;
492
493 if (resource->type != VME_MASTER) {
ead1f3e3 494 printk(KERN_ERR "Not a master resource\n");
a17a75e2
MW
495 return -EINVAL;
496 }
497
498 image = list_entry(resource->entry, struct vme_master_resource, list);
499
500 if (bridge->master_set == NULL) {
ead1f3e3 501 printk(KERN_WARNING "vme_master_set not supported\n");
a17a75e2
MW
502 return -EINVAL;
503 }
504
ead1f3e3 505 if (!(((image->address_attr & aspace) == aspace) &&
a17a75e2
MW
506 ((image->cycle_attr & cycle) == cycle) &&
507 ((image->width_attr & dwidth) == dwidth))) {
ead1f3e3 508 printk(KERN_WARNING "Invalid attributes\n");
a17a75e2
MW
509 return -EINVAL;
510 }
511
512 retval = vme_check_window(aspace, vme_base, size);
ead1f3e3 513 if (retval)
a17a75e2
MW
514 return retval;
515
516 return bridge->master_set(image, enabled, vme_base, size, aspace,
517 cycle, dwidth);
518}
519EXPORT_SYMBOL(vme_master_set);
520
ead1f3e3 521int vme_master_get(struct vme_resource *resource, int *enabled,
6af04b06
MW
522 unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
523 u32 *cycle, u32 *dwidth)
a17a75e2
MW
524{
525 struct vme_bridge *bridge = find_bridge(resource);
526 struct vme_master_resource *image;
527
528 if (resource->type != VME_MASTER) {
ead1f3e3 529 printk(KERN_ERR "Not a master resource\n");
a17a75e2
MW
530 return -EINVAL;
531 }
532
533 image = list_entry(resource->entry, struct vme_master_resource, list);
534
51a569f7 535 if (bridge->master_get == NULL) {
c1038307 536 printk(KERN_WARNING "%s not supported\n", __func__);
a17a75e2
MW
537 return -EINVAL;
538 }
539
540 return bridge->master_get(image, enabled, vme_base, size, aspace,
541 cycle, dwidth);
542}
543EXPORT_SYMBOL(vme_master_get);
544
545/*
546 * Read data out of VME space into a buffer.
547 */
ead1f3e3 548ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count,
a17a75e2
MW
549 loff_t offset)
550{
551 struct vme_bridge *bridge = find_bridge(resource);
552 struct vme_master_resource *image;
553 size_t length;
554
555 if (bridge->master_read == NULL) {
ead1f3e3 556 printk(KERN_WARNING "Reading from resource not supported\n");
a17a75e2
MW
557 return -EINVAL;
558 }
559
560 if (resource->type != VME_MASTER) {
ead1f3e3 561 printk(KERN_ERR "Not a master resource\n");
a17a75e2
MW
562 return -EINVAL;
563 }
564
565 image = list_entry(resource->entry, struct vme_master_resource, list);
566
567 length = vme_get_size(resource);
568
569 if (offset > length) {
ead1f3e3 570 printk(KERN_WARNING "Invalid Offset\n");
a17a75e2
MW
571 return -EFAULT;
572 }
573
574 if ((offset + count) > length)
575 count = length - offset;
576
577 return bridge->master_read(image, buf, count, offset);
578
579}
580EXPORT_SYMBOL(vme_master_read);
581
582/*
583 * Write data out to VME space from a buffer.
584 */
ead1f3e3 585ssize_t vme_master_write(struct vme_resource *resource, void *buf,
a17a75e2
MW
586 size_t count, loff_t offset)
587{
588 struct vme_bridge *bridge = find_bridge(resource);
589 struct vme_master_resource *image;
590 size_t length;
591
592 if (bridge->master_write == NULL) {
ead1f3e3 593 printk(KERN_WARNING "Writing to resource not supported\n");
a17a75e2
MW
594 return -EINVAL;
595 }
596
597 if (resource->type != VME_MASTER) {
ead1f3e3 598 printk(KERN_ERR "Not a master resource\n");
a17a75e2
MW
599 return -EINVAL;
600 }
601
602 image = list_entry(resource->entry, struct vme_master_resource, list);
603
604 length = vme_get_size(resource);
605
606 if (offset > length) {
ead1f3e3 607 printk(KERN_WARNING "Invalid Offset\n");
a17a75e2
MW
608 return -EFAULT;
609 }
610
611 if ((offset + count) > length)
612 count = length - offset;
613
614 return bridge->master_write(image, buf, count, offset);
615}
616EXPORT_SYMBOL(vme_master_write);
617
618/*
619 * Perform RMW cycle to provided location.
620 */
ead1f3e3 621unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask,
a17a75e2
MW
622 unsigned int compare, unsigned int swap, loff_t offset)
623{
624 struct vme_bridge *bridge = find_bridge(resource);
625 struct vme_master_resource *image;
626
627 if (bridge->master_rmw == NULL) {
ead1f3e3 628 printk(KERN_WARNING "Writing to resource not supported\n");
a17a75e2
MW
629 return -EINVAL;
630 }
631
632 if (resource->type != VME_MASTER) {
ead1f3e3 633 printk(KERN_ERR "Not a master resource\n");
a17a75e2
MW
634 return -EINVAL;
635 }
636
637 image = list_entry(resource->entry, struct vme_master_resource, list);
638
639 return bridge->master_rmw(image, mask, compare, swap, offset);
640}
641EXPORT_SYMBOL(vme_master_rmw);
642
c74a804f
DK
643int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma)
644{
645 struct vme_master_resource *image;
646 phys_addr_t phys_addr;
647 unsigned long vma_size;
648
649 if (resource->type != VME_MASTER) {
650 pr_err("Not a master resource\n");
651 return -EINVAL;
652 }
653
654 image = list_entry(resource->entry, struct vme_master_resource, list);
655 phys_addr = image->bus_resource.start + (vma->vm_pgoff << PAGE_SHIFT);
656 vma_size = vma->vm_end - vma->vm_start;
657
658 if (phys_addr + vma_size > image->bus_resource.end + 1) {
659 pr_err("Map size cannot exceed the window size\n");
660 return -EFAULT;
661 }
662
663 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
664
665 return vm_iomap_memory(vma, phys_addr, vma->vm_end - vma->vm_start);
666}
667EXPORT_SYMBOL(vme_master_mmap);
668
a17a75e2
MW
669void vme_master_free(struct vme_resource *resource)
670{
671 struct vme_master_resource *master_image;
672
673 if (resource->type != VME_MASTER) {
ead1f3e3 674 printk(KERN_ERR "Not a master resource\n");
a17a75e2
MW
675 return;
676 }
677
678 master_image = list_entry(resource->entry, struct vme_master_resource,
679 list);
680 if (master_image == NULL) {
ead1f3e3 681 printk(KERN_ERR "Can't find master resource\n");
a17a75e2
MW
682 return;
683 }
684
685 /* Unlock image */
886953e9 686 spin_lock(&master_image->lock);
a17a75e2
MW
687 if (master_image->locked == 0)
688 printk(KERN_ERR "Image is already free\n");
689
690 master_image->locked = 0;
886953e9 691 spin_unlock(&master_image->lock);
a17a75e2
MW
692
693 /* Free up resource memory */
694 kfree(resource);
695}
696EXPORT_SYMBOL(vme_master_free);
697
698/*
699 * Request a DMA controller with specific attributes, return some unique
700 * identifier.
701 */
6af04b06 702struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route)
a17a75e2
MW
703{
704 struct vme_bridge *bridge;
705 struct list_head *dma_pos = NULL;
706 struct vme_dma_resource *allocated_ctrlr = NULL;
707 struct vme_dma_resource *dma_ctrlr = NULL;
708 struct vme_resource *resource = NULL;
709
710 /* XXX Not checking resource attributes */
711 printk(KERN_ERR "No VME resource Attribute tests done\n");
712
8f966dc4 713 bridge = vdev->bridge;
a17a75e2
MW
714 if (bridge == NULL) {
715 printk(KERN_ERR "Can't find VME bus\n");
716 goto err_bus;
717 }
718
719 /* Loop through DMA resources */
886953e9 720 list_for_each(dma_pos, &bridge->dma_resources) {
a17a75e2
MW
721 dma_ctrlr = list_entry(dma_pos,
722 struct vme_dma_resource, list);
723
724 if (dma_ctrlr == NULL) {
ead1f3e3 725 printk(KERN_ERR "Registered NULL DMA resource\n");
a17a75e2
MW
726 continue;
727 }
728
4f723df4 729 /* Find an unlocked and compatible controller */
886953e9 730 mutex_lock(&dma_ctrlr->mtx);
4f723df4
MW
731 if (((dma_ctrlr->route_attr & route) == route) &&
732 (dma_ctrlr->locked == 0)) {
733
a17a75e2 734 dma_ctrlr->locked = 1;
886953e9 735 mutex_unlock(&dma_ctrlr->mtx);
a17a75e2
MW
736 allocated_ctrlr = dma_ctrlr;
737 break;
738 }
886953e9 739 mutex_unlock(&dma_ctrlr->mtx);
a17a75e2
MW
740 }
741
742 /* Check to see if we found a resource */
743 if (allocated_ctrlr == NULL)
744 goto err_ctrlr;
745
746 resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
747 if (resource == NULL) {
748 printk(KERN_WARNING "Unable to allocate resource structure\n");
749 goto err_alloc;
750 }
751 resource->type = VME_DMA;
886953e9 752 resource->entry = &allocated_ctrlr->list;
a17a75e2
MW
753
754 return resource;
755
756err_alloc:
757 /* Unlock image */
886953e9 758 mutex_lock(&dma_ctrlr->mtx);
a17a75e2 759 dma_ctrlr->locked = 0;
886953e9 760 mutex_unlock(&dma_ctrlr->mtx);
a17a75e2
MW
761err_ctrlr:
762err_bus:
763 return NULL;
764}
58e50798 765EXPORT_SYMBOL(vme_dma_request);
a17a75e2
MW
766
767/*
768 * Start new list
769 */
770struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource)
771{
772 struct vme_dma_resource *ctrlr;
773 struct vme_dma_list *dma_list;
774
775 if (resource->type != VME_DMA) {
ead1f3e3 776 printk(KERN_ERR "Not a DMA resource\n");
a17a75e2
MW
777 return NULL;
778 }
779
780 ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
781
ead1f3e3
MW
782 dma_list = kmalloc(sizeof(struct vme_dma_list), GFP_KERNEL);
783 if (dma_list == NULL) {
f56c3d4f 784 printk(KERN_ERR "Unable to allocate memory for new DMA list\n");
a17a75e2
MW
785 return NULL;
786 }
886953e9 787 INIT_LIST_HEAD(&dma_list->entries);
a17a75e2 788 dma_list->parent = ctrlr;
886953e9 789 mutex_init(&dma_list->mtx);
a17a75e2
MW
790
791 return dma_list;
792}
793EXPORT_SYMBOL(vme_new_dma_list);
794
795/*
796 * Create "Pattern" type attributes
797 */
6af04b06 798struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type)
a17a75e2
MW
799{
800 struct vme_dma_attr *attributes;
801 struct vme_dma_pattern *pattern_attr;
802
ead1f3e3
MW
803 attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL);
804 if (attributes == NULL) {
25958ce3 805 printk(KERN_ERR "Unable to allocate memory for attributes structure\n");
a17a75e2
MW
806 goto err_attr;
807 }
808
ead1f3e3
MW
809 pattern_attr = kmalloc(sizeof(struct vme_dma_pattern), GFP_KERNEL);
810 if (pattern_attr == NULL) {
25958ce3 811 printk(KERN_ERR "Unable to allocate memory for pattern attributes\n");
a17a75e2
MW
812 goto err_pat;
813 }
814
815 attributes->type = VME_DMA_PATTERN;
816 attributes->private = (void *)pattern_attr;
817
818 pattern_attr->pattern = pattern;
819 pattern_attr->type = type;
820
821 return attributes;
822
a17a75e2
MW
823err_pat:
824 kfree(attributes);
825err_attr:
826 return NULL;
827}
828EXPORT_SYMBOL(vme_dma_pattern_attribute);
829
830/*
831 * Create "PCI" type attributes
832 */
833struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address)
834{
835 struct vme_dma_attr *attributes;
836 struct vme_dma_pci *pci_attr;
837
838 /* XXX Run some sanity checks here */
839
ead1f3e3
MW
840 attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL);
841 if (attributes == NULL) {
25958ce3 842 printk(KERN_ERR "Unable to allocate memory for attributes structure\n");
a17a75e2
MW
843 goto err_attr;
844 }
845
ead1f3e3
MW
846 pci_attr = kmalloc(sizeof(struct vme_dma_pci), GFP_KERNEL);
847 if (pci_attr == NULL) {
f56c3d4f 848 printk(KERN_ERR "Unable to allocate memory for PCI attributes\n");
a17a75e2
MW
849 goto err_pci;
850 }
851
852
853
854 attributes->type = VME_DMA_PCI;
855 attributes->private = (void *)pci_attr;
856
857 pci_attr->address = address;
858
859 return attributes;
860
a17a75e2
MW
861err_pci:
862 kfree(attributes);
863err_attr:
864 return NULL;
865}
866EXPORT_SYMBOL(vme_dma_pci_attribute);
867
868/*
869 * Create "VME" type attributes
870 */
871struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address,
6af04b06 872 u32 aspace, u32 cycle, u32 dwidth)
a17a75e2
MW
873{
874 struct vme_dma_attr *attributes;
875 struct vme_dma_vme *vme_attr;
876
ead1f3e3 877 attributes = kmalloc(
a17a75e2 878 sizeof(struct vme_dma_attr), GFP_KERNEL);
ead1f3e3 879 if (attributes == NULL) {
25958ce3 880 printk(KERN_ERR "Unable to allocate memory for attributes structure\n");
a17a75e2
MW
881 goto err_attr;
882 }
883
ead1f3e3
MW
884 vme_attr = kmalloc(sizeof(struct vme_dma_vme), GFP_KERNEL);
885 if (vme_attr == NULL) {
f56c3d4f 886 printk(KERN_ERR "Unable to allocate memory for VME attributes\n");
a17a75e2
MW
887 goto err_vme;
888 }
889
890 attributes->type = VME_DMA_VME;
891 attributes->private = (void *)vme_attr;
892
893 vme_attr->address = address;
894 vme_attr->aspace = aspace;
895 vme_attr->cycle = cycle;
896 vme_attr->dwidth = dwidth;
897
898 return attributes;
899
a17a75e2
MW
900err_vme:
901 kfree(attributes);
902err_attr:
903 return NULL;
904}
905EXPORT_SYMBOL(vme_dma_vme_attribute);
906
907/*
908 * Free attribute
909 */
910void vme_dma_free_attribute(struct vme_dma_attr *attributes)
911{
912 kfree(attributes->private);
913 kfree(attributes);
914}
915EXPORT_SYMBOL(vme_dma_free_attribute);
916
917int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
918 struct vme_dma_attr *dest, size_t count)
919{
920 struct vme_bridge *bridge = list->parent->parent;
921 int retval;
922
923 if (bridge->dma_list_add == NULL) {
ead1f3e3 924 printk(KERN_WARNING "Link List DMA generation not supported\n");
a17a75e2
MW
925 return -EINVAL;
926 }
927
886953e9 928 if (!mutex_trylock(&list->mtx)) {
ead1f3e3 929 printk(KERN_ERR "Link List already submitted\n");
a17a75e2
MW
930 return -EINVAL;
931 }
932
933 retval = bridge->dma_list_add(list, src, dest, count);
934
886953e9 935 mutex_unlock(&list->mtx);
a17a75e2
MW
936
937 return retval;
938}
939EXPORT_SYMBOL(vme_dma_list_add);
940
941int vme_dma_list_exec(struct vme_dma_list *list)
942{
943 struct vme_bridge *bridge = list->parent->parent;
944 int retval;
945
946 if (bridge->dma_list_exec == NULL) {
ead1f3e3 947 printk(KERN_ERR "Link List DMA execution not supported\n");
a17a75e2
MW
948 return -EINVAL;
949 }
950
886953e9 951 mutex_lock(&list->mtx);
a17a75e2
MW
952
953 retval = bridge->dma_list_exec(list);
954
886953e9 955 mutex_unlock(&list->mtx);
a17a75e2
MW
956
957 return retval;
958}
959EXPORT_SYMBOL(vme_dma_list_exec);
960
961int vme_dma_list_free(struct vme_dma_list *list)
962{
963 struct vme_bridge *bridge = list->parent->parent;
964 int retval;
965
966 if (bridge->dma_list_empty == NULL) {
ead1f3e3 967 printk(KERN_WARNING "Emptying of Link Lists not supported\n");
a17a75e2
MW
968 return -EINVAL;
969 }
970
886953e9 971 if (!mutex_trylock(&list->mtx)) {
ead1f3e3 972 printk(KERN_ERR "Link List in use\n");
a17a75e2
MW
973 return -EINVAL;
974 }
975
976 /*
f56c3d4f
AS
977 * Empty out all of the entries from the DMA list. We need to go to the
978 * low level driver as DMA entries are driver specific.
a17a75e2
MW
979 */
980 retval = bridge->dma_list_empty(list);
981 if (retval) {
ead1f3e3 982 printk(KERN_ERR "Unable to empty link-list entries\n");
886953e9 983 mutex_unlock(&list->mtx);
a17a75e2
MW
984 return retval;
985 }
886953e9 986 mutex_unlock(&list->mtx);
a17a75e2
MW
987 kfree(list);
988
989 return retval;
990}
991EXPORT_SYMBOL(vme_dma_list_free);
992
993int vme_dma_free(struct vme_resource *resource)
994{
995 struct vme_dma_resource *ctrlr;
996
997 if (resource->type != VME_DMA) {
ead1f3e3 998 printk(KERN_ERR "Not a DMA resource\n");
a17a75e2
MW
999 return -EINVAL;
1000 }
1001
1002 ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
1003
886953e9 1004 if (!mutex_trylock(&ctrlr->mtx)) {
ead1f3e3 1005 printk(KERN_ERR "Resource busy, can't free\n");
a17a75e2
MW
1006 return -EBUSY;
1007 }
1008
886953e9 1009 if (!(list_empty(&ctrlr->pending) && list_empty(&ctrlr->running))) {
ead1f3e3 1010 printk(KERN_WARNING "Resource still processing transfers\n");
886953e9 1011 mutex_unlock(&ctrlr->mtx);
a17a75e2
MW
1012 return -EBUSY;
1013 }
1014
1015 ctrlr->locked = 0;
1016
886953e9 1017 mutex_unlock(&ctrlr->mtx);
a17a75e2 1018
fd5c2561
MW
1019 kfree(resource);
1020
a17a75e2
MW
1021 return 0;
1022}
1023EXPORT_SYMBOL(vme_dma_free);
1024
e2c6393f 1025void vme_bus_error_handler(struct vme_bridge *bridge,
472f16f3 1026 unsigned long long address, int am)
e2c6393f 1027{
0b049662
DK
1028 struct list_head *handler_pos = NULL;
1029 struct vme_error_handler *handler;
448535a3 1030 int handler_triggered = 0;
0b049662
DK
1031 u32 aspace = vme_get_aspace(am);
1032
1033 list_for_each(handler_pos, &bridge->vme_error_handlers) {
1034 handler = list_entry(handler_pos, struct vme_error_handler,
1035 list);
1036 if ((aspace == handler->aspace) &&
1037 (address >= handler->start) &&
1038 (address < handler->end)) {
1039 if (!handler->num_errors)
1040 handler->first_error = address;
1041 if (handler->num_errors != UINT_MAX)
1042 handler->num_errors++;
448535a3 1043 handler_triggered = 1;
0b049662 1044 }
e2c6393f 1045 }
448535a3
DK
1046
1047 if (!handler_triggered)
1048 dev_err(bridge->parent,
1049 "Unhandled VME access error at address 0x%llx\n",
1050 address);
e2c6393f
DK
1051}
1052EXPORT_SYMBOL(vme_bus_error_handler);
1053
0b049662
DK
1054struct vme_error_handler *vme_register_error_handler(
1055 struct vme_bridge *bridge, u32 aspace,
1056 unsigned long long address, size_t len)
e2c6393f 1057{
0b049662 1058 struct vme_error_handler *handler;
e2c6393f 1059
0b049662
DK
1060 handler = kmalloc(sizeof(*handler), GFP_KERNEL);
1061 if (!handler)
1062 return NULL;
e2c6393f 1063
0b049662
DK
1064 handler->aspace = aspace;
1065 handler->start = address;
1066 handler->end = address + len;
1067 handler->num_errors = 0;
1068 handler->first_error = 0;
1069 list_add_tail(&handler->list, &bridge->vme_error_handlers);
e2c6393f 1070
0b049662 1071 return handler;
e2c6393f 1072}
0b049662 1073EXPORT_SYMBOL(vme_register_error_handler);
e2c6393f 1074
0b049662 1075void vme_unregister_error_handler(struct vme_error_handler *handler)
e2c6393f 1076{
0b049662
DK
1077 list_del(&handler->list);
1078 kfree(handler);
e2c6393f 1079}
0b049662 1080EXPORT_SYMBOL(vme_unregister_error_handler);
e2c6393f 1081
c813f592
MW
1082void vme_irq_handler(struct vme_bridge *bridge, int level, int statid)
1083{
1084 void (*call)(int, int, void *);
1085 void *priv_data;
1086
1087 call = bridge->irq[level - 1].callback[statid].func;
1088 priv_data = bridge->irq[level - 1].callback[statid].priv_data;
1089
1090 if (call != NULL)
1091 call(level, statid, priv_data);
1092 else
f56c3d4f 1093 printk(KERN_WARNING "Spurious VME interrupt, level:%x, vector:%x\n",
25958ce3 1094 level, statid);
c813f592
MW
1095}
1096EXPORT_SYMBOL(vme_irq_handler);
1097
8f966dc4 1098int vme_irq_request(struct vme_dev *vdev, int level, int statid,
29848ac9 1099 void (*callback)(int, int, void *),
a17a75e2
MW
1100 void *priv_data)
1101{
1102 struct vme_bridge *bridge;
1103
8f966dc4 1104 bridge = vdev->bridge;
a17a75e2
MW
1105 if (bridge == NULL) {
1106 printk(KERN_ERR "Can't find VME bus\n");
1107 return -EINVAL;
1108 }
1109
ead1f3e3 1110 if ((level < 1) || (level > 7)) {
c813f592 1111 printk(KERN_ERR "Invalid interrupt level\n");
a17a75e2
MW
1112 return -EINVAL;
1113 }
1114
c813f592
MW
1115 if (bridge->irq_set == NULL) {
1116 printk(KERN_ERR "Configuring interrupts not supported\n");
a17a75e2
MW
1117 return -EINVAL;
1118 }
1119
886953e9 1120 mutex_lock(&bridge->irq_mtx);
c813f592
MW
1121
1122 if (bridge->irq[level - 1].callback[statid].func) {
886953e9 1123 mutex_unlock(&bridge->irq_mtx);
c813f592
MW
1124 printk(KERN_WARNING "VME Interrupt already taken\n");
1125 return -EBUSY;
1126 }
1127
1128 bridge->irq[level - 1].count++;
1129 bridge->irq[level - 1].callback[statid].priv_data = priv_data;
1130 bridge->irq[level - 1].callback[statid].func = callback;
1131
1132 /* Enable IRQ level */
29848ac9 1133 bridge->irq_set(bridge, level, 1, 1);
c813f592 1134
886953e9 1135 mutex_unlock(&bridge->irq_mtx);
c813f592
MW
1136
1137 return 0;
a17a75e2 1138}
c813f592 1139EXPORT_SYMBOL(vme_irq_request);
a17a75e2 1140
8f966dc4 1141void vme_irq_free(struct vme_dev *vdev, int level, int statid)
a17a75e2
MW
1142{
1143 struct vme_bridge *bridge;
1144
8f966dc4 1145 bridge = vdev->bridge;
a17a75e2
MW
1146 if (bridge == NULL) {
1147 printk(KERN_ERR "Can't find VME bus\n");
1148 return;
1149 }
1150
ead1f3e3 1151 if ((level < 1) || (level > 7)) {
c813f592 1152 printk(KERN_ERR "Invalid interrupt level\n");
a17a75e2
MW
1153 return;
1154 }
1155
c813f592
MW
1156 if (bridge->irq_set == NULL) {
1157 printk(KERN_ERR "Configuring interrupts not supported\n");
a17a75e2
MW
1158 return;
1159 }
1160
886953e9 1161 mutex_lock(&bridge->irq_mtx);
c813f592
MW
1162
1163 bridge->irq[level - 1].count--;
1164
1165 /* Disable IRQ level if no more interrupts attached at this level*/
1166 if (bridge->irq[level - 1].count == 0)
29848ac9 1167 bridge->irq_set(bridge, level, 0, 1);
c813f592
MW
1168
1169 bridge->irq[level - 1].callback[statid].func = NULL;
1170 bridge->irq[level - 1].callback[statid].priv_data = NULL;
1171
886953e9 1172 mutex_unlock(&bridge->irq_mtx);
a17a75e2 1173}
c813f592 1174EXPORT_SYMBOL(vme_irq_free);
a17a75e2 1175
8f966dc4 1176int vme_irq_generate(struct vme_dev *vdev, int level, int statid)
a17a75e2
MW
1177{
1178 struct vme_bridge *bridge;
1179
8f966dc4 1180 bridge = vdev->bridge;
a17a75e2
MW
1181 if (bridge == NULL) {
1182 printk(KERN_ERR "Can't find VME bus\n");
1183 return -EINVAL;
1184 }
1185
ead1f3e3 1186 if ((level < 1) || (level > 7)) {
a17a75e2
MW
1187 printk(KERN_WARNING "Invalid interrupt level\n");
1188 return -EINVAL;
1189 }
1190
c813f592 1191 if (bridge->irq_generate == NULL) {
ead1f3e3 1192 printk(KERN_WARNING "Interrupt generation not supported\n");
a17a75e2
MW
1193 return -EINVAL;
1194 }
1195
29848ac9 1196 return bridge->irq_generate(bridge, level, statid);
a17a75e2 1197}
c813f592 1198EXPORT_SYMBOL(vme_irq_generate);
a17a75e2 1199
42fb5031
MW
1200/*
1201 * Request the location monitor, return resource or NULL
1202 */
8f966dc4 1203struct vme_resource *vme_lm_request(struct vme_dev *vdev)
a17a75e2
MW
1204{
1205 struct vme_bridge *bridge;
42fb5031
MW
1206 struct list_head *lm_pos = NULL;
1207 struct vme_lm_resource *allocated_lm = NULL;
1208 struct vme_lm_resource *lm = NULL;
1209 struct vme_resource *resource = NULL;
a17a75e2 1210
8f966dc4 1211 bridge = vdev->bridge;
a17a75e2
MW
1212 if (bridge == NULL) {
1213 printk(KERN_ERR "Can't find VME bus\n");
42fb5031
MW
1214 goto err_bus;
1215 }
1216
1217 /* Loop through DMA resources */
886953e9 1218 list_for_each(lm_pos, &bridge->lm_resources) {
42fb5031
MW
1219 lm = list_entry(lm_pos,
1220 struct vme_lm_resource, list);
1221
1222 if (lm == NULL) {
25958ce3 1223 printk(KERN_ERR "Registered NULL Location Monitor resource\n");
42fb5031
MW
1224 continue;
1225 }
1226
1227 /* Find an unlocked controller */
886953e9 1228 mutex_lock(&lm->mtx);
42fb5031
MW
1229 if (lm->locked == 0) {
1230 lm->locked = 1;
886953e9 1231 mutex_unlock(&lm->mtx);
42fb5031
MW
1232 allocated_lm = lm;
1233 break;
1234 }
886953e9 1235 mutex_unlock(&lm->mtx);
42fb5031
MW
1236 }
1237
1238 /* Check to see if we found a resource */
1239 if (allocated_lm == NULL)
1240 goto err_lm;
1241
1242 resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
1243 if (resource == NULL) {
1244 printk(KERN_ERR "Unable to allocate resource structure\n");
1245 goto err_alloc;
1246 }
1247 resource->type = VME_LM;
886953e9 1248 resource->entry = &allocated_lm->list;
42fb5031
MW
1249
1250 return resource;
1251
1252err_alloc:
1253 /* Unlock image */
886953e9 1254 mutex_lock(&lm->mtx);
42fb5031 1255 lm->locked = 0;
886953e9 1256 mutex_unlock(&lm->mtx);
42fb5031
MW
1257err_lm:
1258err_bus:
1259 return NULL;
1260}
1261EXPORT_SYMBOL(vme_lm_request);
1262
1263int vme_lm_count(struct vme_resource *resource)
1264{
1265 struct vme_lm_resource *lm;
1266
1267 if (resource->type != VME_LM) {
1268 printk(KERN_ERR "Not a Location Monitor resource\n");
1269 return -EINVAL;
1270 }
1271
1272 lm = list_entry(resource->entry, struct vme_lm_resource, list);
1273
1274 return lm->monitors;
1275}
1276EXPORT_SYMBOL(vme_lm_count);
1277
1278int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base,
6af04b06 1279 u32 aspace, u32 cycle)
42fb5031
MW
1280{
1281 struct vme_bridge *bridge = find_bridge(resource);
1282 struct vme_lm_resource *lm;
1283
1284 if (resource->type != VME_LM) {
1285 printk(KERN_ERR "Not a Location Monitor resource\n");
a17a75e2
MW
1286 return -EINVAL;
1287 }
1288
42fb5031
MW
1289 lm = list_entry(resource->entry, struct vme_lm_resource, list);
1290
a17a75e2 1291 if (bridge->lm_set == NULL) {
42fb5031 1292 printk(KERN_ERR "vme_lm_set not supported\n");
a17a75e2
MW
1293 return -EINVAL;
1294 }
1295
8be9226c 1296 return bridge->lm_set(lm, lm_base, aspace, cycle);
a17a75e2
MW
1297}
1298EXPORT_SYMBOL(vme_lm_set);
1299
42fb5031 1300int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base,
6af04b06 1301 u32 *aspace, u32 *cycle)
a17a75e2 1302{
42fb5031
MW
1303 struct vme_bridge *bridge = find_bridge(resource);
1304 struct vme_lm_resource *lm;
a17a75e2 1305
42fb5031
MW
1306 if (resource->type != VME_LM) {
1307 printk(KERN_ERR "Not a Location Monitor resource\n");
a17a75e2
MW
1308 return -EINVAL;
1309 }
1310
42fb5031
MW
1311 lm = list_entry(resource->entry, struct vme_lm_resource, list);
1312
a17a75e2 1313 if (bridge->lm_get == NULL) {
42fb5031 1314 printk(KERN_ERR "vme_lm_get not supported\n");
a17a75e2
MW
1315 return -EINVAL;
1316 }
1317
42fb5031 1318 return bridge->lm_get(lm, lm_base, aspace, cycle);
a17a75e2
MW
1319}
1320EXPORT_SYMBOL(vme_lm_get);
1321
42fb5031 1322int vme_lm_attach(struct vme_resource *resource, int monitor,
fa54b326 1323 void (*callback)(void *), void *data)
a17a75e2 1324{
42fb5031
MW
1325 struct vme_bridge *bridge = find_bridge(resource);
1326 struct vme_lm_resource *lm;
a17a75e2 1327
42fb5031
MW
1328 if (resource->type != VME_LM) {
1329 printk(KERN_ERR "Not a Location Monitor resource\n");
a17a75e2
MW
1330 return -EINVAL;
1331 }
1332
42fb5031
MW
1333 lm = list_entry(resource->entry, struct vme_lm_resource, list);
1334
a17a75e2 1335 if (bridge->lm_attach == NULL) {
42fb5031 1336 printk(KERN_ERR "vme_lm_attach not supported\n");
a17a75e2
MW
1337 return -EINVAL;
1338 }
1339
fa54b326 1340 return bridge->lm_attach(lm, monitor, callback, data);
a17a75e2
MW
1341}
1342EXPORT_SYMBOL(vme_lm_attach);
1343
42fb5031 1344int vme_lm_detach(struct vme_resource *resource, int monitor)
a17a75e2 1345{
42fb5031
MW
1346 struct vme_bridge *bridge = find_bridge(resource);
1347 struct vme_lm_resource *lm;
a17a75e2 1348
42fb5031
MW
1349 if (resource->type != VME_LM) {
1350 printk(KERN_ERR "Not a Location Monitor resource\n");
a17a75e2
MW
1351 return -EINVAL;
1352 }
1353
42fb5031
MW
1354 lm = list_entry(resource->entry, struct vme_lm_resource, list);
1355
a17a75e2 1356 if (bridge->lm_detach == NULL) {
42fb5031 1357 printk(KERN_ERR "vme_lm_detach not supported\n");
a17a75e2
MW
1358 return -EINVAL;
1359 }
1360
42fb5031 1361 return bridge->lm_detach(lm, monitor);
a17a75e2
MW
1362}
1363EXPORT_SYMBOL(vme_lm_detach);
1364
42fb5031
MW
1365void vme_lm_free(struct vme_resource *resource)
1366{
1367 struct vme_lm_resource *lm;
1368
1369 if (resource->type != VME_LM) {
1370 printk(KERN_ERR "Not a Location Monitor resource\n");
1371 return;
1372 }
1373
1374 lm = list_entry(resource->entry, struct vme_lm_resource, list);
1375
886953e9 1376 mutex_lock(&lm->mtx);
42fb5031 1377
8be9226c
MW
1378 /* XXX
1379 * Check to see that there aren't any callbacks still attached, if
1380 * there are we should probably be detaching them!
1381 */
42fb5031
MW
1382
1383 lm->locked = 0;
1384
886953e9 1385 mutex_unlock(&lm->mtx);
8be9226c
MW
1386
1387 kfree(resource);
42fb5031
MW
1388}
1389EXPORT_SYMBOL(vme_lm_free);
1390
d7729f0f 1391int vme_slot_num(struct vme_dev *vdev)
a17a75e2
MW
1392{
1393 struct vme_bridge *bridge;
1394
8f966dc4 1395 bridge = vdev->bridge;
a17a75e2
MW
1396 if (bridge == NULL) {
1397 printk(KERN_ERR "Can't find VME bus\n");
1398 return -EINVAL;
1399 }
1400
1401 if (bridge->slot_get == NULL) {
d7729f0f 1402 printk(KERN_WARNING "vme_slot_num not supported\n");
a17a75e2
MW
1403 return -EINVAL;
1404 }
1405
29848ac9 1406 return bridge->slot_get(bridge);
a17a75e2 1407}
d7729f0f 1408EXPORT_SYMBOL(vme_slot_num);
a17a75e2 1409
978f47d6
MW
1410int vme_bus_num(struct vme_dev *vdev)
1411{
1412 struct vme_bridge *bridge;
1413
1414 bridge = vdev->bridge;
1415 if (bridge == NULL) {
1416 pr_err("Can't find VME bus\n");
1417 return -EINVAL;
1418 }
1419
1420 return bridge->num;
1421}
1422EXPORT_SYMBOL(vme_bus_num);
a17a75e2
MW
1423
1424/* - Bridge Registration --------------------------------------------------- */
1425
5b93c2a2
MV
1426static void vme_dev_release(struct device *dev)
1427{
1428 kfree(dev_to_vme_dev(dev));
1429}
1430
326071b3
AS
1431/* Common bridge initialization */
1432struct vme_bridge *vme_init_bridge(struct vme_bridge *bridge)
1433{
1434 INIT_LIST_HEAD(&bridge->vme_error_handlers);
1435 INIT_LIST_HEAD(&bridge->master_resources);
1436 INIT_LIST_HEAD(&bridge->slave_resources);
1437 INIT_LIST_HEAD(&bridge->dma_resources);
1438 INIT_LIST_HEAD(&bridge->lm_resources);
1439 mutex_init(&bridge->irq_mtx);
1440
1441 return bridge;
1442}
1443EXPORT_SYMBOL(vme_init_bridge);
1444
5b93c2a2 1445int vme_register_bridge(struct vme_bridge *bridge)
a17a75e2
MW
1446{
1447 int i;
733e3ef0 1448 int ret = -1;
a17a75e2 1449
733e3ef0 1450 mutex_lock(&vme_buses_lock);
a17a75e2 1451 for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) {
733e3ef0
MV
1452 if ((vme_bus_numbers & (1 << i)) == 0) {
1453 vme_bus_numbers |= (1 << i);
1454 bridge->num = i;
5d6abf37 1455 INIT_LIST_HEAD(&bridge->devices);
733e3ef0
MV
1456 list_add_tail(&bridge->bus_list, &vme_bus_list);
1457 ret = 0;
a17a75e2
MW
1458 break;
1459 }
1460 }
733e3ef0 1461 mutex_unlock(&vme_buses_lock);
a17a75e2 1462
733e3ef0 1463 return ret;
a17a75e2 1464}
5b93c2a2 1465EXPORT_SYMBOL(vme_register_bridge);
a17a75e2 1466
5b93c2a2 1467void vme_unregister_bridge(struct vme_bridge *bridge)
a17a75e2 1468{
5d6abf37
MV
1469 struct vme_dev *vdev;
1470 struct vme_dev *tmp;
1471
733e3ef0
MV
1472 mutex_lock(&vme_buses_lock);
1473 vme_bus_numbers &= ~(1 << bridge->num);
5d6abf37
MV
1474 list_for_each_entry_safe(vdev, tmp, &bridge->devices, bridge_list) {
1475 list_del(&vdev->drv_list);
1476 list_del(&vdev->bridge_list);
1477 device_unregister(&vdev->dev);
1478 }
733e3ef0
MV
1479 list_del(&bridge->bus_list);
1480 mutex_unlock(&vme_buses_lock);
a17a75e2 1481}
5d6abf37 1482EXPORT_SYMBOL(vme_unregister_bridge);
a17a75e2 1483
5d6abf37
MV
1484/* - Driver Registration --------------------------------------------------- */
1485
1486static int __vme_register_driver_bus(struct vme_driver *drv,
1487 struct vme_bridge *bridge, unsigned int ndevs)
1488{
1489 int err;
1490 unsigned int i;
1491 struct vme_dev *vdev;
1492 struct vme_dev *tmp;
1493
1494 for (i = 0; i < ndevs; i++) {
1495 vdev = kzalloc(sizeof(struct vme_dev), GFP_KERNEL);
1496 if (!vdev) {
1497 err = -ENOMEM;
f6c39d4f
MV
1498 goto err_devalloc;
1499 }
a916a391 1500 vdev->num = i;
8f966dc4 1501 vdev->bridge = bridge;
5d6abf37
MV
1502 vdev->dev.platform_data = drv;
1503 vdev->dev.release = vme_dev_release;
8f966dc4
MV
1504 vdev->dev.parent = bridge->parent;
1505 vdev->dev.bus = &vme_bus_type;
a916a391
MV
1506 dev_set_name(&vdev->dev, "%s.%u-%u", drv->name, bridge->num,
1507 vdev->num);
a17a75e2 1508
5d6abf37
MV
1509 err = device_register(&vdev->dev);
1510 if (err)
a17a75e2 1511 goto err_reg;
a17a75e2 1512
5d6abf37
MV
1513 if (vdev->dev.platform_data) {
1514 list_add_tail(&vdev->drv_list, &drv->devices);
1515 list_add_tail(&vdev->bridge_list, &bridge->devices);
1516 } else
1517 device_unregister(&vdev->dev);
1518 }
1519 return 0;
a17a75e2 1520
a17a75e2 1521err_reg:
def1820d 1522 put_device(&vdev->dev);
8f966dc4 1523 kfree(vdev);
f6c39d4f 1524err_devalloc:
5d6abf37
MV
1525 list_for_each_entry_safe(vdev, tmp, &drv->devices, drv_list) {
1526 list_del(&vdev->drv_list);
1527 list_del(&vdev->bridge_list);
8f966dc4 1528 device_unregister(&vdev->dev);
a17a75e2 1529 }
5d6abf37 1530 return err;
a17a75e2 1531}
a17a75e2 1532
5d6abf37 1533static int __vme_register_driver(struct vme_driver *drv, unsigned int ndevs)
a17a75e2 1534{
5d6abf37
MV
1535 struct vme_bridge *bridge;
1536 int err = 0;
a17a75e2 1537
5d6abf37
MV
1538 mutex_lock(&vme_buses_lock);
1539 list_for_each_entry(bridge, &vme_bus_list, bus_list) {
1540 /*
1541 * This cannot cause trouble as we already have vme_buses_lock
1542 * and if the bridge is removed, it will have to go through
1543 * vme_unregister_bridge() to do it (which calls remove() on
1544 * the bridge which in turn tries to acquire vme_buses_lock and
c26f6112 1545 * will have to wait).
5d6abf37
MV
1546 */
1547 err = __vme_register_driver_bus(drv, bridge, ndevs);
1548 if (err)
1549 break;
a17a75e2 1550 }
5d6abf37
MV
1551 mutex_unlock(&vme_buses_lock);
1552 return err;
a17a75e2 1553}
a17a75e2 1554
5d6abf37 1555int vme_register_driver(struct vme_driver *drv, unsigned int ndevs)
a17a75e2 1556{
5d6abf37
MV
1557 int err;
1558
a17a75e2
MW
1559 drv->driver.name = drv->name;
1560 drv->driver.bus = &vme_bus_type;
5d6abf37
MV
1561 INIT_LIST_HEAD(&drv->devices);
1562
1563 err = driver_register(&drv->driver);
1564 if (err)
1565 return err;
a17a75e2 1566
5d6abf37
MV
1567 err = __vme_register_driver(drv, ndevs);
1568 if (err)
1569 driver_unregister(&drv->driver);
1570
1571 return err;
a17a75e2
MW
1572}
1573EXPORT_SYMBOL(vme_register_driver);
1574
ead1f3e3 1575void vme_unregister_driver(struct vme_driver *drv)
a17a75e2 1576{
5d6abf37
MV
1577 struct vme_dev *dev, *dev_tmp;
1578
1579 mutex_lock(&vme_buses_lock);
1580 list_for_each_entry_safe(dev, dev_tmp, &drv->devices, drv_list) {
1581 list_del(&dev->drv_list);
1582 list_del(&dev->bridge_list);
1583 device_unregister(&dev->dev);
1584 }
1585 mutex_unlock(&vme_buses_lock);
1586
a17a75e2
MW
1587 driver_unregister(&drv->driver);
1588}
1589EXPORT_SYMBOL(vme_unregister_driver);
1590
1591/* - Bus Registration ------------------------------------------------------ */
1592
a17a75e2
MW
1593static int vme_bus_match(struct device *dev, struct device_driver *drv)
1594{
5d6abf37 1595 struct vme_driver *vme_drv;
a17a75e2 1596
5d6abf37 1597 vme_drv = container_of(drv, struct vme_driver, driver);
a17a75e2 1598
5d6abf37
MV
1599 if (dev->platform_data == vme_drv) {
1600 struct vme_dev *vdev = dev_to_vme_dev(dev);
a17a75e2 1601
5d6abf37
MV
1602 if (vme_drv->match && vme_drv->match(vdev))
1603 return 1;
a37b0dad 1604
5d6abf37 1605 dev->platform_data = NULL;
a17a75e2 1606 }
a17a75e2
MW
1607 return 0;
1608}
1609
1610static int vme_bus_probe(struct device *dev)
1611{
a17a75e2 1612 int retval = -ENODEV;
5d6abf37
MV
1613 struct vme_driver *driver;
1614 struct vme_dev *vdev = dev_to_vme_dev(dev);
a17a75e2 1615
5d6abf37 1616 driver = dev->platform_data;
a17a75e2 1617
ead1f3e3 1618 if (driver->probe != NULL)
8f966dc4 1619 retval = driver->probe(vdev);
a17a75e2
MW
1620
1621 return retval;
1622}
1623
a17a75e2
MW
1624struct bus_type vme_bus_type = {
1625 .name = "vme",
1626 .match = vme_bus_match,
1627 .probe = vme_bus_probe,
a17a75e2
MW
1628};
1629EXPORT_SYMBOL(vme_bus_type);
1630
ead1f3e3 1631static int __init vme_init(void)
a17a75e2
MW
1632{
1633 return bus_register(&vme_bus_type);
1634}
c326cc02 1635subsys_initcall(vme_init);
This page took 0.748793 seconds and 5 git commands to generate.