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