Linux Audio

Check our new training course

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