File Index
Files and directories
Sign in
FILE

vme.c

File preview with syntax highlighting.

linux-6.19.14/drivers/staging/vme_user/vme.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * VME Bridge Framework
   4 *
   5 * Author: Martyn Welch <martyn.welch@ge.com>
   6 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
   7 *
   8 * Based on work by Tom Armistead and Ajit Prem
   9 * Copyright 2004 Motorola Inc.
  10 */
  11
  12#include <linux/init.h>
  13#include <linux/export.h>
  14#include <linux/mm.h>
  15#include <linux/types.h>
  16#include <linux/kernel.h>
  17#include <linux/errno.h>
  18#include <linux/pci.h>
  19#include <linux/poll.h>
  20#include <linux/highmem.h>
  21#include <linux/interrupt.h>
  22#include <linux/pagemap.h>
  23#include <linux/device.h>
  24#include <linux/dma-mapping.h>
  25#include <linux/syscalls.h>
  26#include <linux/mutex.h>
  27#include <linux/spinlock.h>
  28#include <linux/slab.h>
  29
  30#include "vme.h"
  31#include "vme_bridge.h"
  32
  33/* Bitmask and list of registered buses both protected by common mutex */
  34static unsigned int vme_bus_numbers;
  35static LIST_HEAD(vme_bus_list);
  36static DEFINE_MUTEX(vme_buses_lock);
  37
  38static int __init vme_init(void);
  39
  40static struct vme_dev *dev_to_vme_dev(struct device *dev)
  41{
  42	return container_of(dev, struct vme_dev, dev);
  43}
  44
  45/*
  46 * Find the bridge that the resource is associated with.
  47 */
  48static struct vme_bridge *find_bridge(struct vme_resource *resource)
  49{
  50	/* Get list to search */
  51	switch (resource->type) {
  52	case VME_MASTER:
  53		return list_entry(resource->entry, struct vme_master_resource,
  54			list)->parent;
  55	case VME_SLAVE:
  56		return list_entry(resource->entry, struct vme_slave_resource,
  57			list)->parent;
  58	case VME_DMA:
  59		return list_entry(resource->entry, struct vme_dma_resource,
  60			list)->parent;
  61	case VME_LM:
  62		return list_entry(resource->entry, struct vme_lm_resource,
  63			list)->parent;
  64	default:
  65		return NULL;
  66	}
  67}
  68
  69/**
  70 * vme_alloc_consistent - Allocate contiguous memory.
  71 * @resource: Pointer to VME resource.
  72 * @size: Size of allocation required.
  73 * @dma: Pointer to variable to store physical address of allocation.
  74 *
  75 * Allocate a contiguous block of memory for use by the driver. This is used to
  76 * create the buffers for the slave windows.
  77 *
  78 * Return: Virtual address of allocation on success, NULL on failure.
  79 */
  80void *vme_alloc_consistent(struct vme_resource *resource, size_t size,
  81			   dma_addr_t *dma)
  82{
  83	struct vme_bridge *bridge = find_bridge(resource);
  84
  85	if (!bridge->alloc_consistent) {
  86		dev_err(bridge->parent,
  87			"alloc_consistent not supported by bridge %s\n",
  88			bridge->name);
  89		return NULL;
  90	}
  91
  92	return bridge->alloc_consistent(bridge->parent, size, dma);
  93}
  94EXPORT_SYMBOL(vme_alloc_consistent);
  95
  96/**
  97 * vme_free_consistent - Free previously allocated memory.
  98 * @resource: Pointer to VME resource.
  99 * @size: Size of allocation to free.
 100 * @vaddr: Virtual address of allocation.
 101 * @dma: Physical address of allocation.
 102 *
 103 * Free previously allocated block of contiguous memory.
 104 */
 105void vme_free_consistent(struct vme_resource *resource, size_t size,
 106			 void *vaddr, dma_addr_t dma)
 107{
 108	struct vme_bridge *bridge = find_bridge(resource);
 109
 110	if (!bridge->free_consistent) {
 111		dev_err(bridge->parent,
 112			"free_consistent not supported by bridge %s\n",
 113			bridge->name);
 114		return;
 115	}
 116
 117	bridge->free_consistent(bridge->parent, size, vaddr, dma);
 118}
 119EXPORT_SYMBOL(vme_free_consistent);
 120
 121/**
 122 * vme_get_size - Helper function returning size of a VME window
 123 * @resource: Pointer to VME slave or master resource.
 124 *
 125 * Determine the size of the VME window provided. This is a helper
 126 * function, wrappering the call to vme_master_get or vme_slave_get
 127 * depending on the type of window resource handed to it.
 128 *
 129 * Return: Size of the window on success, zero on failure.
 130 */
 131size_t vme_get_size(struct vme_resource *resource)
 132{
 133	struct vme_bridge *bridge = find_bridge(resource);
 134	int enabled, retval;
 135	unsigned long long base, size;
 136	dma_addr_t buf_base;
 137	u32 aspace, cycle, dwidth;
 138
 139	switch (resource->type) {
 140	case VME_MASTER:
 141		retval = vme_master_get(resource, &enabled, &base, &size,
 142					&aspace, &cycle, &dwidth);
 143		if (retval)
 144			return 0;
 145
 146		return size;
 147	case VME_SLAVE:
 148		retval = vme_slave_get(resource, &enabled, &base, &size,
 149				       &buf_base, &aspace, &cycle);
 150		if (retval)
 151			return 0;
 152
 153		return size;
 154	case VME_DMA:
 155		return 0;
 156	default:
 157		dev_err(bridge->parent, "Unknown resource type\n");
 158		return 0;
 159	}
 160}
 161EXPORT_SYMBOL(vme_get_size);
 162
 163int vme_check_window(struct vme_bridge *bridge, u32 aspace,
 164		     unsigned long long vme_base, unsigned long long size)
 165{
 166	int retval = 0;
 167
 168	if (vme_base + size < size)
 169		return -EINVAL;
 170
 171	switch (aspace) {
 172	case VME_A16:
 173		if (vme_base + size > VME_A16_MAX)
 174			retval = -EFAULT;
 175		break;
 176	case VME_A24:
 177		if (vme_base + size > VME_A24_MAX)
 178			retval = -EFAULT;
 179		break;
 180	case VME_A32:
 181		if (vme_base + size > VME_A32_MAX)
 182			retval = -EFAULT;
 183		break;
 184	case VME_A64:
 185		/* The VME_A64_MAX limit is actually U64_MAX + 1 */
 186		break;
 187	case VME_CRCSR:
 188		if (vme_base + size > VME_CRCSR_MAX)
 189			retval = -EFAULT;
 190		break;
 191	case VME_USER1:
 192	case VME_USER2:
 193	case VME_USER3:
 194	case VME_USER4:
 195		/* User Defined */
 196		break;
 197	default:
 198		dev_err(bridge->parent, "Invalid address space\n");
 199		retval = -EINVAL;
 200		break;
 201	}
 202
 203	return retval;
 204}
 205EXPORT_SYMBOL(vme_check_window);
 206
 207static u32 vme_get_aspace(int am)
 208{
 209	switch (am) {
 210	case 0x29:
 211	case 0x2D:
 212		return VME_A16;
 213	case 0x38:
 214	case 0x39:
 215	case 0x3A:
 216	case 0x3B:
 217	case 0x3C:
 218	case 0x3D:
 219	case 0x3E:
 220	case 0x3F:
 221		return VME_A24;
 222	case 0x8:
 223	case 0x9:
 224	case 0xA:
 225	case 0xB:
 226	case 0xC:
 227	case 0xD:
 228	case 0xE:
 229	case 0xF:
 230		return VME_A32;
 231	case 0x0:
 232	case 0x1:
 233	case 0x3:
 234		return VME_A64;
 235	}
 236
 237	return 0;
 238}
 239
 240/**
 241 * vme_slave_request - Request a VME slave window resource.
 242 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 243 * @address: Required VME address space.
 244 * @cycle: Required VME data transfer cycle type.
 245 *
 246 * Request use of a VME window resource capable of being set for the requested
 247 * address space and data transfer cycle.
 248 *
 249 * Return: Pointer to VME resource on success, NULL on failure.
 250 */
 251struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address,
 252				       u32 cycle)
 253{
 254	struct vme_bridge *bridge;
 255	struct vme_slave_resource *allocated_image = NULL;
 256	struct vme_slave_resource *slave_image = NULL;
 257	struct vme_resource *resource = NULL;
 258
 259	bridge = vdev->bridge;
 260	if (!bridge) {
 261		dev_err(&vdev->dev, "Can't find VME bus\n");
 262		goto err_bus;
 263	}
 264
 265	/* Loop through slave resources */
 266	list_for_each_entry(slave_image, &bridge->slave_resources, list) {
 267		if (!slave_image) {
 268			dev_err(bridge->parent,
 269				"Registered NULL Slave resource\n");
 270			continue;
 271		}
 272
 273		/* Find an unlocked and compatible image */
 274		mutex_lock(&slave_image->mtx);
 275		if (((slave_image->address_attr & address) == address) &&
 276		    ((slave_image->cycle_attr & cycle) == cycle) &&
 277		    (slave_image->locked == 0)) {
 278			slave_image->locked = 1;
 279			mutex_unlock(&slave_image->mtx);
 280			allocated_image = slave_image;
 281			break;
 282		}
 283		mutex_unlock(&slave_image->mtx);
 284	}
 285
 286	/* No free image */
 287	if (!allocated_image)
 288		goto err_image;
 289
 290	resource = kmalloc(sizeof(*resource), GFP_KERNEL);
 291	if (!resource)
 292		goto err_alloc;
 293
 294	resource->type = VME_SLAVE;
 295	resource->entry = &allocated_image->list;
 296
 297	return resource;
 298
 299err_alloc:
 300	/* Unlock image */
 301	mutex_lock(&slave_image->mtx);
 302	slave_image->locked = 0;
 303	mutex_unlock(&slave_image->mtx);
 304err_image:
 305err_bus:
 306	return NULL;
 307}
 308EXPORT_SYMBOL(vme_slave_request);
 309
 310/**
 311 * vme_slave_set - Set VME slave window configuration.
 312 * @resource: Pointer to VME slave resource.
 313 * @enabled: State to which the window should be configured.
 314 * @vme_base: Base address for the window.
 315 * @size: Size of the VME window.
 316 * @buf_base: Based address of buffer used to provide VME slave window storage.
 317 * @aspace: VME address space for the VME window.
 318 * @cycle: VME data transfer cycle type for the VME window.
 319 *
 320 * Set configuration for provided VME slave window.
 321 *
 322 * Return: Zero on success, -EINVAL if operation is not supported on this
 323 *         device, if an invalid resource has been provided or invalid
 324 *         attributes are provided. Hardware specific errors may also be
 325 *         returned.
 326 */
 327int vme_slave_set(struct vme_resource *resource, int enabled,
 328		  unsigned long long vme_base, unsigned long long size,
 329		  dma_addr_t buf_base, u32 aspace, u32 cycle)
 330{
 331	struct vme_bridge *bridge = find_bridge(resource);
 332	struct vme_slave_resource *image;
 333	int retval;
 334
 335	if (resource->type != VME_SLAVE) {
 336		dev_err(bridge->parent, "Not a slave resource\n");
 337		return -EINVAL;
 338	}
 339
 340	image = list_entry(resource->entry, struct vme_slave_resource, list);
 341
 342	if (!bridge->slave_set) {
 343		dev_err(bridge->parent, "%s not supported\n", __func__);
 344		return -EINVAL;
 345	}
 346
 347	if (!(((image->address_attr & aspace) == aspace) &&
 348	      ((image->cycle_attr & cycle) == cycle))) {
 349		dev_err(bridge->parent, "Invalid attributes\n");
 350		return -EINVAL;
 351	}
 352
 353	retval = vme_check_window(bridge, aspace, vme_base, size);
 354	if (retval)
 355		return retval;
 356
 357	return bridge->slave_set(image, enabled, vme_base, size, buf_base,
 358		aspace, cycle);
 359}
 360EXPORT_SYMBOL(vme_slave_set);
 361
 362/**
 363 * vme_slave_get - Retrieve VME slave window configuration.
 364 * @resource: Pointer to VME slave resource.
 365 * @enabled: Pointer to variable for storing state.
 366 * @vme_base: Pointer to variable for storing window base address.
 367 * @size: Pointer to variable for storing window size.
 368 * @buf_base: Pointer to variable for storing slave buffer base address.
 369 * @aspace: Pointer to variable for storing VME address space.
 370 * @cycle: Pointer to variable for storing VME data transfer cycle type.
 371 *
 372 * Return configuration for provided VME slave window.
 373 *
 374 * Return: Zero on success, -EINVAL if operation is not supported on this
 375 *         device or if an invalid resource has been provided.
 376 */
 377int vme_slave_get(struct vme_resource *resource, int *enabled,
 378		  unsigned long long *vme_base, unsigned long long *size,
 379		  dma_addr_t *buf_base, u32 *aspace, u32 *cycle)
 380{
 381	struct vme_bridge *bridge = find_bridge(resource);
 382	struct vme_slave_resource *image;
 383
 384	if (resource->type != VME_SLAVE) {
 385		dev_err(bridge->parent, "Not a slave resource\n");
 386		return -EINVAL;
 387	}
 388
 389	image = list_entry(resource->entry, struct vme_slave_resource, list);
 390
 391	if (!bridge->slave_get) {
 392		dev_err(bridge->parent, "%s not supported\n", __func__);
 393		return -EINVAL;
 394	}
 395
 396	return bridge->slave_get(image, enabled, vme_base, size, buf_base,
 397		aspace, cycle);
 398}
 399EXPORT_SYMBOL(vme_slave_get);
 400
 401/**
 402 * vme_slave_free - Free VME slave window
 403 * @resource: Pointer to VME slave resource.
 404 *
 405 * Free the provided slave resource so that it may be reallocated.
 406 */
 407void vme_slave_free(struct vme_resource *resource)
 408{
 409	struct vme_bridge *bridge = find_bridge(resource);
 410	struct vme_slave_resource *slave_image;
 411
 412	if (resource->type != VME_SLAVE) {
 413		dev_err(bridge->parent, "Not a slave resource\n");
 414		return;
 415	}
 416
 417	slave_image = list_entry(resource->entry, struct vme_slave_resource,
 418				 list);
 419
 420	/* Unlock image */
 421	mutex_lock(&slave_image->mtx);
 422	if (slave_image->locked == 0)
 423		dev_err(bridge->parent, "Image is already free\n");
 424
 425	slave_image->locked = 0;
 426	mutex_unlock(&slave_image->mtx);
 427
 428	/* Free up resource memory */
 429	kfree(resource);
 430}
 431EXPORT_SYMBOL(vme_slave_free);
 432
 433/**
 434 * vme_master_request - Request a VME master window resource.
 435 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 436 * @address: Required VME address space.
 437 * @cycle: Required VME data transfer cycle type.
 438 * @dwidth: Required VME data transfer width.
 439 *
 440 * Request use of a VME window resource capable of being set for the requested
 441 * address space, data transfer cycle and width.
 442 *
 443 * Return: Pointer to VME resource on success, NULL on failure.
 444 */
 445struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address,
 446					u32 cycle, u32 dwidth)
 447{
 448	struct vme_bridge *bridge;
 449	struct vme_master_resource *allocated_image = NULL;
 450	struct vme_master_resource *master_image = NULL;
 451	struct vme_resource *resource = NULL;
 452
 453	bridge = vdev->bridge;
 454	if (!bridge) {
 455		dev_err(&vdev->dev, "Can't find VME bus\n");
 456		goto err_bus;
 457	}
 458
 459	/* Loop through master resources */
 460	list_for_each_entry(master_image, &bridge->master_resources, list) {
 461		if (!master_image) {
 462			dev_warn(bridge->parent,
 463				 "Registered NULL master resource\n");
 464			continue;
 465		}
 466
 467		/* Find an unlocked and compatible image */
 468		spin_lock(&master_image->lock);
 469		if (((master_image->address_attr & address) == address) &&
 470		    ((master_image->cycle_attr & cycle) == cycle) &&
 471		    ((master_image->width_attr & dwidth) == dwidth) &&
 472		    (master_image->locked == 0)) {
 473			master_image->locked = 1;
 474			spin_unlock(&master_image->lock);
 475			allocated_image = master_image;
 476			break;
 477		}
 478		spin_unlock(&master_image->lock);
 479	}
 480
 481	/* Check to see if we found a resource */
 482	if (!allocated_image) {
 483		dev_err(&vdev->dev, "Can't find a suitable resource\n");
 484		goto err_image;
 485	}
 486
 487	resource = kmalloc(sizeof(*resource), GFP_KERNEL);
 488	if (!resource)
 489		goto err_alloc;
 490
 491	resource->type = VME_MASTER;
 492	resource->entry = &allocated_image->list;
 493
 494	return resource;
 495
 496err_alloc:
 497	/* Unlock image */
 498	spin_lock(&master_image->lock);
 499	master_image->locked = 0;
 500	spin_unlock(&master_image->lock);
 501err_image:
 502err_bus:
 503	return NULL;
 504}
 505EXPORT_SYMBOL(vme_master_request);
 506
 507/**
 508 * vme_master_set - Set VME master window configuration.
 509 * @resource: Pointer to VME master resource.
 510 * @enabled: State to which the window should be configured.
 511 * @vme_base: Base address for the window.
 512 * @size: Size of the VME window.
 513 * @aspace: VME address space for the VME window.
 514 * @cycle: VME data transfer cycle type for the VME window.
 515 * @dwidth: VME data transfer width for the VME window.
 516 *
 517 * Set configuration for provided VME master window.
 518 *
 519 * Return: Zero on success, -EINVAL if operation is not supported on this
 520 *         device, if an invalid resource has been provided or invalid
 521 *         attributes are provided. Hardware specific errors may also be
 522 *         returned.
 523 */
 524int vme_master_set(struct vme_resource *resource, int enabled,
 525		   unsigned long long vme_base, unsigned long long size,
 526		   u32 aspace, u32 cycle, u32 dwidth)
 527{
 528	struct vme_bridge *bridge = find_bridge(resource);
 529	struct vme_master_resource *image;
 530	int retval;
 531
 532	if (resource->type != VME_MASTER) {
 533		dev_err(bridge->parent, "Not a master resource\n");
 534		return -EINVAL;
 535	}
 536
 537	image = list_entry(resource->entry, struct vme_master_resource, list);
 538
 539	if (!bridge->master_set) {
 540		dev_warn(bridge->parent, "%s not supported\n", __func__);
 541		return -EINVAL;
 542	}
 543
 544	if (!(((image->address_attr & aspace) == aspace) &&
 545	      ((image->cycle_attr & cycle) == cycle) &&
 546	      ((image->width_attr & dwidth) == dwidth))) {
 547		dev_warn(bridge->parent, "Invalid attributes\n");
 548		return -EINVAL;
 549	}
 550
 551	retval = vme_check_window(bridge, aspace, vme_base, size);
 552	if (retval)
 553		return retval;
 554
 555	return bridge->master_set(image, enabled, vme_base, size, aspace,
 556		cycle, dwidth);
 557}
 558EXPORT_SYMBOL(vme_master_set);
 559
 560/**
 561 * vme_master_get - Retrieve VME master window configuration.
 562 * @resource: Pointer to VME master resource.
 563 * @enabled: Pointer to variable for storing state.
 564 * @vme_base: Pointer to variable for storing window base address.
 565 * @size: Pointer to variable for storing window size.
 566 * @aspace: Pointer to variable for storing VME address space.
 567 * @cycle: Pointer to variable for storing VME data transfer cycle type.
 568 * @dwidth: Pointer to variable for storing VME data transfer width.
 569 *
 570 * Return configuration for provided VME master window.
 571 *
 572 * Return: Zero on success, -EINVAL if operation is not supported on this
 573 *         device or if an invalid resource has been provided.
 574 */
 575int vme_master_get(struct vme_resource *resource, int *enabled,
 576		   unsigned long long *vme_base, unsigned long long *size,
 577		   u32 *aspace, u32 *cycle, u32 *dwidth)
 578{
 579	struct vme_bridge *bridge = find_bridge(resource);
 580	struct vme_master_resource *image;
 581
 582	if (resource->type != VME_MASTER) {
 583		dev_err(bridge->parent, "Not a master resource\n");
 584		return -EINVAL;
 585	}
 586
 587	image = list_entry(resource->entry, struct vme_master_resource, list);
 588
 589	if (!bridge->master_get) {
 590		dev_warn(bridge->parent, "%s not supported\n", __func__);
 591		return -EINVAL;
 592	}
 593
 594	return bridge->master_get(image, enabled, vme_base, size, aspace,
 595		cycle, dwidth);
 596}
 597EXPORT_SYMBOL(vme_master_get);
 598
 599/**
 600 * vme_master_read - Read data from VME space into a buffer.
 601 * @resource: Pointer to VME master resource.
 602 * @buf: Pointer to buffer where data should be transferred.
 603 * @count: Number of bytes to transfer.
 604 * @offset: Offset into VME master window at which to start transfer.
 605 *
 606 * Perform read of count bytes of data from location on VME bus which maps into
 607 * the VME master window at offset to buf.
 608 *
 609 * Return: Number of bytes read, -EINVAL if resource is not a VME master
 610 *         resource or read operation is not supported. -EFAULT returned if
 611 *         invalid offset is provided. Hardware specific errors may also be
 612 *         returned.
 613 */
 614ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count,
 615			loff_t offset)
 616{
 617	struct vme_bridge *bridge = find_bridge(resource);
 618	struct vme_master_resource *image;
 619	size_t length;
 620
 621	if (!bridge->master_read) {
 622		dev_warn(bridge->parent,
 623			 "Reading from resource not supported\n");
 624		return -EINVAL;
 625	}
 626
 627	if (resource->type != VME_MASTER) {
 628		dev_err(bridge->parent, "Not a master resource\n");
 629		return -EINVAL;
 630	}
 631
 632	image = list_entry(resource->entry, struct vme_master_resource, list);
 633
 634	length = vme_get_size(resource);
 635
 636	if (offset > length) {
 637		dev_warn(bridge->parent, "Invalid Offset\n");
 638		return -EFAULT;
 639	}
 640
 641	if ((offset + count) > length)
 642		count = length - offset;
 643
 644	return bridge->master_read(image, buf, count, offset);
 645}
 646EXPORT_SYMBOL(vme_master_read);
 647
 648/**
 649 * vme_master_write - Write data out to VME space from a buffer.
 650 * @resource: Pointer to VME master resource.
 651 * @buf: Pointer to buffer holding data to transfer.
 652 * @count: Number of bytes to transfer.
 653 * @offset: Offset into VME master window at which to start transfer.
 654 *
 655 * Perform write of count bytes of data from buf to location on VME bus which
 656 * maps into the VME master window at offset.
 657 *
 658 * Return: Number of bytes written, -EINVAL if resource is not a VME master
 659 *         resource or write operation is not supported. -EFAULT returned if
 660 *         invalid offset is provided. Hardware specific errors may also be
 661 *         returned.
 662 */
 663ssize_t vme_master_write(struct vme_resource *resource, void *buf,
 664			 size_t count, loff_t offset)
 665{
 666	struct vme_bridge *bridge = find_bridge(resource);
 667	struct vme_master_resource *image;
 668	size_t length;
 669
 670	if (!bridge->master_write) {
 671		dev_warn(bridge->parent, "Writing to resource not supported\n");
 672		return -EINVAL;
 673	}
 674
 675	if (resource->type != VME_MASTER) {
 676		dev_err(bridge->parent, "Not a master resource\n");
 677		return -EINVAL;
 678	}
 679
 680	image = list_entry(resource->entry, struct vme_master_resource, list);
 681
 682	length = vme_get_size(resource);
 683
 684	if (offset > length) {
 685		dev_warn(bridge->parent, "Invalid Offset\n");
 686		return -EFAULT;
 687	}
 688
 689	if ((offset + count) > length)
 690		count = length - offset;
 691
 692	return bridge->master_write(image, buf, count, offset);
 693}
 694EXPORT_SYMBOL(vme_master_write);
 695
 696/**
 697 * vme_master_rmw - Perform read-modify-write cycle.
 698 * @resource: Pointer to VME master resource.
 699 * @mask: Bits to be compared and swapped in operation.
 700 * @compare: Bits to be compared with data read from offset.
 701 * @swap: Bits to be swapped in data read from offset.
 702 * @offset: Offset into VME master window at which to perform operation.
 703 *
 704 * Perform read-modify-write cycle on provided location:
 705 * - Location on VME bus is read.
 706 * - Bits selected by mask are compared with compare.
 707 * - Where a selected bit matches that in compare and are selected in swap,
 708 * the bit is swapped.
 709 * - Result written back to location on VME bus.
 710 *
 711 * Return: Bytes written on success, -EINVAL if resource is not a VME master
 712 *         resource or RMW operation is not supported. Hardware specific
 713 *         errors may also be returned.
 714 */
 715unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask,
 716			    unsigned int compare, unsigned int swap, loff_t offset)
 717{
 718	struct vme_bridge *bridge = find_bridge(resource);
 719	struct vme_master_resource *image;
 720
 721	if (!bridge->master_rmw) {
 722		dev_warn(bridge->parent, "Writing to resource not supported\n");
 723		return -EINVAL;
 724	}
 725
 726	if (resource->type != VME_MASTER) {
 727		dev_err(bridge->parent, "Not a master resource\n");
 728		return -EINVAL;
 729	}
 730
 731	image = list_entry(resource->entry, struct vme_master_resource, list);
 732
 733	return bridge->master_rmw(image, mask, compare, swap, offset);
 734}
 735EXPORT_SYMBOL(vme_master_rmw);
 736
 737/**
 738 * vme_master_mmap - Mmap region of VME master window.
 739 * @resource: Pointer to VME master resource.
 740 * @vma: Pointer to definition of user mapping.
 741 *
 742 * Memory map a region of the VME master window into user space.
 743 *
 744 * Return: Zero on success, -EINVAL if resource is not a VME master
 745 *         resource or -EFAULT if map exceeds window size. Other generic mmap
 746 *         errors may also be returned.
 747 */
 748int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma)
 749{
 750	struct vme_bridge *bridge = find_bridge(resource);
 751	struct vme_master_resource *image;
 752	phys_addr_t phys_addr;
 753	unsigned long vma_size;
 754
 755	if (resource->type != VME_MASTER) {
 756		dev_err(bridge->parent, "Not a master resource\n");
 757		return -EINVAL;
 758	}
 759
 760	image = list_entry(resource->entry, struct vme_master_resource, list);
 761	phys_addr = image->bus_resource.start + (vma->vm_pgoff << PAGE_SHIFT);
 762	vma_size = vma->vm_end - vma->vm_start;
 763
 764	if (phys_addr + vma_size > image->bus_resource.end + 1) {
 765		dev_err(bridge->parent, "Map size cannot exceed the window size\n");
 766		return -EFAULT;
 767	}
 768
 769	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 770
 771	return vm_iomap_memory(vma, phys_addr, vma->vm_end - vma->vm_start);
 772}
 773EXPORT_SYMBOL(vme_master_mmap);
 774
 775/**
 776 * vme_master_free - Free VME master window
 777 * @resource: Pointer to VME master resource.
 778 *
 779 * Free the provided master resource so that it may be reallocated.
 780 */
 781void vme_master_free(struct vme_resource *resource)
 782{
 783	struct vme_bridge *bridge = find_bridge(resource);
 784	struct vme_master_resource *master_image;
 785
 786	if (resource->type != VME_MASTER) {
 787		dev_err(bridge->parent, "Not a master resource\n");
 788		return;
 789	}
 790
 791	master_image = list_entry(resource->entry, struct vme_master_resource,
 792				  list);
 793
 794	/* Unlock image */
 795	spin_lock(&master_image->lock);
 796	if (master_image->locked == 0)
 797		dev_err(bridge->parent, "Image is already free\n");
 798
 799	master_image->locked = 0;
 800	spin_unlock(&master_image->lock);
 801
 802	/* Free up resource memory */
 803	kfree(resource);
 804}
 805EXPORT_SYMBOL(vme_master_free);
 806
 807/**
 808 * vme_dma_request - Request a DMA controller.
 809 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 810 * @route: Required src/destination combination.
 811 *
 812 * Request a VME DMA controller with capability to perform transfers between
 813 * requested source/destination combination.
 814 *
 815 * Return: Pointer to VME DMA resource on success, NULL on failure.
 816 */
 817struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route)
 818{
 819	struct vme_bridge *bridge;
 820	struct vme_dma_resource *allocated_ctrlr = NULL;
 821	struct vme_dma_resource *dma_ctrlr = NULL;
 822	struct vme_resource *resource = NULL;
 823
 824	/* XXX Not checking resource attributes */
 825	dev_err(&vdev->dev, "No VME resource Attribute tests done\n");
 826
 827	bridge = vdev->bridge;
 828	if (!bridge) {
 829		dev_err(&vdev->dev, "Can't find VME bus\n");
 830		goto err_bus;
 831	}
 832
 833	/* Loop through DMA resources */
 834	list_for_each_entry(dma_ctrlr, &bridge->dma_resources, list) {
 835		if (!dma_ctrlr) {
 836			dev_err(bridge->parent,
 837				"Registered NULL DMA resource\n");
 838			continue;
 839		}
 840
 841		/* Find an unlocked and compatible controller */
 842		mutex_lock(&dma_ctrlr->mtx);
 843		if (((dma_ctrlr->route_attr & route) == route) &&
 844		    (dma_ctrlr->locked == 0)) {
 845			dma_ctrlr->locked = 1;
 846			mutex_unlock(&dma_ctrlr->mtx);
 847			allocated_ctrlr = dma_ctrlr;
 848			break;
 849		}
 850		mutex_unlock(&dma_ctrlr->mtx);
 851	}
 852
 853	/* Check to see if we found a resource */
 854	if (!allocated_ctrlr)
 855		goto err_ctrlr;
 856
 857	resource = kmalloc(sizeof(*resource), GFP_KERNEL);
 858	if (!resource)
 859		goto err_alloc;
 860
 861	resource->type = VME_DMA;
 862	resource->entry = &allocated_ctrlr->list;
 863
 864	return resource;
 865
 866err_alloc:
 867	/* Unlock image */
 868	mutex_lock(&dma_ctrlr->mtx);
 869	dma_ctrlr->locked = 0;
 870	mutex_unlock(&dma_ctrlr->mtx);
 871err_ctrlr:
 872err_bus:
 873	return NULL;
 874}
 875EXPORT_SYMBOL(vme_dma_request);
 876
 877/**
 878 * vme_new_dma_list - Create new VME DMA list.
 879 * @resource: Pointer to VME DMA resource.
 880 *
 881 * Create a new VME DMA list. It is the responsibility of the user to free
 882 * the list once it is no longer required with vme_dma_list_free().
 883 *
 884 * Return: Pointer to new VME DMA list, NULL on allocation failure or invalid
 885 *         VME DMA resource.
 886 */
 887struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource)
 888{
 889	struct vme_bridge *bridge = find_bridge(resource);
 890	struct vme_dma_list *dma_list;
 891
 892	if (resource->type != VME_DMA) {
 893		dev_err(bridge->parent, "Not a DMA resource\n");
 894		return NULL;
 895	}
 896
 897	dma_list = kmalloc(sizeof(*dma_list), GFP_KERNEL);
 898	if (!dma_list)
 899		return NULL;
 900
 901	INIT_LIST_HEAD(&dma_list->entries);
 902	dma_list->parent = list_entry(resource->entry,
 903				      struct vme_dma_resource,
 904				      list);
 905	mutex_init(&dma_list->mtx);
 906
 907	return dma_list;
 908}
 909EXPORT_SYMBOL(vme_new_dma_list);
 910
 911/**
 912 * vme_dma_pattern_attribute - Create "Pattern" type VME DMA list attribute.
 913 * @pattern: Value to use used as pattern
 914 * @type: Type of pattern to be written.
 915 *
 916 * Create VME DMA list attribute for pattern generation. It is the
 917 * responsibility of the user to free used attributes using
 918 * vme_dma_free_attribute().
 919 *
 920 * Return: Pointer to VME DMA attribute, NULL on failure.
 921 */
 922struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type)
 923{
 924	struct vme_dma_attr *attributes;
 925	struct vme_dma_pattern *pattern_attr;
 926
 927	attributes = kmalloc(sizeof(*attributes), GFP_KERNEL);
 928	if (!attributes)
 929		goto err_attr;
 930
 931	pattern_attr = kmalloc(sizeof(*pattern_attr), GFP_KERNEL);
 932	if (!pattern_attr)
 933		goto err_pat;
 934
 935	attributes->type = VME_DMA_PATTERN;
 936	attributes->private = (void *)pattern_attr;
 937
 938	pattern_attr->pattern = pattern;
 939	pattern_attr->type = type;
 940
 941	return attributes;
 942
 943err_pat:
 944	kfree(attributes);
 945err_attr:
 946	return NULL;
 947}
 948EXPORT_SYMBOL(vme_dma_pattern_attribute);
 949
 950/**
 951 * vme_dma_pci_attribute - Create "PCI" type VME DMA list attribute.
 952 * @address: PCI base address for DMA transfer.
 953 *
 954 * Create VME DMA list attribute pointing to a location on PCI for DMA
 955 * transfers. It is the responsibility of the user to free used attributes
 956 * using vme_dma_free_attribute().
 957 *
 958 * Return: Pointer to VME DMA attribute, NULL on failure.
 959 */
 960struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address)
 961{
 962	struct vme_dma_attr *attributes;
 963	struct vme_dma_pci *pci_attr;
 964
 965	/* XXX Run some sanity checks here */
 966
 967	attributes = kmalloc(sizeof(*attributes), GFP_KERNEL);
 968	if (!attributes)
 969		goto err_attr;
 970
 971	pci_attr = kmalloc(sizeof(*pci_attr), GFP_KERNEL);
 972	if (!pci_attr)
 973		goto err_pci;
 974
 975	attributes->type = VME_DMA_PCI;
 976	attributes->private = (void *)pci_attr;
 977
 978	pci_attr->address = address;
 979
 980	return attributes;
 981
 982err_pci:
 983	kfree(attributes);
 984err_attr:
 985	return NULL;
 986}
 987EXPORT_SYMBOL(vme_dma_pci_attribute);
 988
 989/**
 990 * vme_dma_vme_attribute - Create "VME" type VME DMA list attribute.
 991 * @address: VME base address for DMA transfer.
 992 * @aspace: VME address space to use for DMA transfer.
 993 * @cycle: VME bus cycle to use for DMA transfer.
 994 * @dwidth: VME data width to use for DMA transfer.
 995 *
 996 * Create VME DMA list attribute pointing to a location on the VME bus for DMA
 997 * transfers. It is the responsibility of the user to free used attributes
 998 * using vme_dma_free_attribute().
 999 *
1000 * Return: Pointer to VME DMA attribute, NULL on failure.
1001 */
1002struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address,
1003					   u32 aspace, u32 cycle, u32 dwidth)
1004{
1005	struct vme_dma_attr *attributes;
1006	struct vme_dma_vme *vme_attr;
1007
1008	attributes = kmalloc(sizeof(*attributes), GFP_KERNEL);
1009	if (!attributes)
1010		goto err_attr;
1011
1012	vme_attr = kmalloc(sizeof(*vme_attr), GFP_KERNEL);
1013	if (!vme_attr)
1014		goto err_vme;
1015
1016	attributes->type = VME_DMA_VME;
1017	attributes->private = (void *)vme_attr;
1018
1019	vme_attr->address = address;
1020	vme_attr->aspace = aspace;
1021	vme_attr->cycle = cycle;
1022	vme_attr->dwidth = dwidth;
1023
1024	return attributes;
1025
1026err_vme:
1027	kfree(attributes);
1028err_attr:
1029	return NULL;
1030}
1031EXPORT_SYMBOL(vme_dma_vme_attribute);
1032
1033/**
1034 * vme_dma_free_attribute - Free DMA list attribute.
1035 * @attributes: Pointer to DMA list attribute.
1036 *
1037 * Free VME DMA list attribute. VME DMA list attributes can be safely freed
1038 * once vme_dma_list_add() has returned.
1039 */
1040void vme_dma_free_attribute(struct vme_dma_attr *attributes)
1041{
1042	kfree(attributes->private);
1043	kfree(attributes);
1044}
1045EXPORT_SYMBOL(vme_dma_free_attribute);
1046
1047/**
1048 * vme_dma_list_add - Add entry to a VME DMA list.
1049 * @list: Pointer to VME list.
1050 * @src: Pointer to DMA list attribute to use as source.
1051 * @dest: Pointer to DMA list attribute to use as destination.
1052 * @count: Number of bytes to transfer.
1053 *
1054 * Add an entry to the provided VME DMA list. Entry requires pointers to source
1055 * and destination DMA attributes and a count.
1056 *
1057 * Please note, the attributes supported as source and destinations for
1058 * transfers are hardware dependent.
1059 *
1060 * Return: Zero on success, -EINVAL if operation is not supported on this
1061 *         device or if the link list has already been submitted for execution.
1062 *         Hardware specific errors also possible.
1063 */
1064int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
1065		     struct vme_dma_attr *dest, size_t count)
1066{
1067	struct vme_bridge *bridge = list->parent->parent;
1068	int retval;
1069
1070	if (!bridge->dma_list_add) {
1071		dev_warn(bridge->parent,
1072			 "Link List DMA generation not supported\n");
1073		return -EINVAL;
1074	}
1075
1076	if (!mutex_trylock(&list->mtx)) {
1077		dev_err(bridge->parent, "Link List already submitted\n");
1078		return -EINVAL;
1079	}
1080
1081	retval = bridge->dma_list_add(list, src, dest, count);
1082
1083	mutex_unlock(&list->mtx);
1084
1085	return retval;
1086}
1087EXPORT_SYMBOL(vme_dma_list_add);
1088
1089/**
1090 * vme_dma_list_exec - Queue a VME DMA list for execution.
1091 * @list: Pointer to VME list.
1092 *
1093 * Queue the provided VME DMA list for execution. The call will return once the
1094 * list has been executed.
1095 *
1096 * Return: Zero on success, -EINVAL if operation is not supported on this
1097 *         device. Hardware specific errors also possible.
1098 */
1099int vme_dma_list_exec(struct vme_dma_list *list)
1100{
1101	struct vme_bridge *bridge = list->parent->parent;
1102	int retval;
1103
1104	if (!bridge->dma_list_exec) {
1105		dev_err(bridge->parent,
1106			"Link List DMA execution not supported\n");
1107		return -EINVAL;
1108	}
1109
1110	mutex_lock(&list->mtx);
1111
1112	retval = bridge->dma_list_exec(list);
1113
1114	mutex_unlock(&list->mtx);
1115
1116	return retval;
1117}
1118EXPORT_SYMBOL(vme_dma_list_exec);
1119
1120/**
1121 * vme_dma_list_free - Free a VME DMA list.
1122 * @list: Pointer to VME list.
1123 *
1124 * Free the provided DMA list and all its entries.
1125 *
1126 * Return: Zero on success, -EINVAL on invalid VME resource, -EBUSY if resource
1127 *         is still in use. Hardware specific errors also possible.
1128 */
1129int vme_dma_list_free(struct vme_dma_list *list)
1130{
1131	struct vme_bridge *bridge = list->parent->parent;
1132	int retval;
1133
1134	if (!bridge->dma_list_empty) {
1135		dev_warn(bridge->parent,
1136			 "Emptying of Link Lists not supported\n");
1137		return -EINVAL;
1138	}
1139
1140	if (!mutex_trylock(&list->mtx)) {
1141		dev_err(bridge->parent, "Link List in use\n");
1142		return -EBUSY;
1143	}
1144
1145	/*
1146	 * Empty out all of the entries from the DMA list. We need to go to the
1147	 * low level driver as DMA entries are driver specific.
1148	 */
1149	retval = bridge->dma_list_empty(list);
1150	if (retval) {
1151		dev_err(bridge->parent, "Unable to empty link-list entries\n");
1152		mutex_unlock(&list->mtx);
1153		return retval;
1154	}
1155	mutex_unlock(&list->mtx);
1156	kfree(list);
1157
1158	return retval;
1159}
1160EXPORT_SYMBOL(vme_dma_list_free);
1161
1162/**
1163 * vme_dma_free - Free a VME DMA resource.
1164 * @resource: Pointer to VME DMA resource.
1165 *
1166 * Free the provided DMA resource so that it may be reallocated.
1167 *
1168 * Return: Zero on success, -EINVAL on invalid VME resource, -EBUSY if resource
1169 *         is still active.
1170 */
1171int vme_dma_free(struct vme_resource *resource)
1172{
1173	struct vme_bridge *bridge = find_bridge(resource);
1174	struct vme_dma_resource *ctrlr;
1175
1176	if (resource->type != VME_DMA) {
1177		dev_err(bridge->parent, "Not a DMA resource\n");
1178		return -EINVAL;
1179	}
1180
1181	ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
1182
1183	if (!mutex_trylock(&ctrlr->mtx)) {
1184		dev_err(bridge->parent, "Resource busy, can't free\n");
1185		return -EBUSY;
1186	}
1187
1188	if (!(list_empty(&ctrlr->pending) && list_empty(&ctrlr->running))) {
1189		dev_warn(bridge->parent,
1190			 "Resource still processing transfers\n");
1191		mutex_unlock(&ctrlr->mtx);
1192		return -EBUSY;
1193	}
1194
1195	ctrlr->locked = 0;
1196
1197	mutex_unlock(&ctrlr->mtx);
1198
1199	kfree(resource);
1200
1201	return 0;
1202}
1203EXPORT_SYMBOL(vme_dma_free);
1204
1205void vme_bus_error_handler(struct vme_bridge *bridge,
1206			   unsigned long long address, int am)
1207{
1208	struct vme_error_handler *handler;
1209	int handler_triggered = 0;
1210	u32 aspace = vme_get_aspace(am);
1211
1212	list_for_each_entry(handler, &bridge->vme_error_handlers, list) {
1213		if ((aspace == handler->aspace) &&
1214		    (address >= handler->start) &&
1215		    (address < handler->end)) {
1216			if (!handler->num_errors)
1217				handler->first_error = address;
1218			if (handler->num_errors != UINT_MAX)
1219				handler->num_errors++;
1220			handler_triggered = 1;
1221		}
1222	}
1223
1224	if (!handler_triggered)
1225		dev_err(bridge->parent,
1226			"Unhandled VME access error at address 0x%llx\n",
1227			address);
1228}
1229EXPORT_SYMBOL(vme_bus_error_handler);
1230
1231struct vme_error_handler *vme_register_error_handler(struct vme_bridge *bridge, u32 aspace,
1232						     unsigned long long address, size_t len)
1233{
1234	struct vme_error_handler *handler;
1235
1236	handler = kmalloc(sizeof(*handler), GFP_ATOMIC);
1237	if (!handler)
1238		return NULL;
1239
1240	handler->aspace = aspace;
1241	handler->start = address;
1242	handler->end = address + len;
1243	handler->num_errors = 0;
1244	handler->first_error = 0;
1245	list_add_tail(&handler->list, &bridge->vme_error_handlers);
1246
1247	return handler;
1248}
1249EXPORT_SYMBOL(vme_register_error_handler);
1250
1251void vme_unregister_error_handler(struct vme_error_handler *handler)
1252{
1253	list_del(&handler->list);
1254	kfree(handler);
1255}
1256EXPORT_SYMBOL(vme_unregister_error_handler);
1257
1258void vme_irq_handler(struct vme_bridge *bridge, int level, int statid)
1259{
1260	void (*call)(int level, int statid, void *priv_data);
1261	void *priv_data;
1262
1263	call = bridge->irq[level - 1].callback[statid].func;
1264	priv_data = bridge->irq[level - 1].callback[statid].priv_data;
1265	if (call)
1266		call(level, statid, priv_data);
1267	else
1268		dev_warn(bridge->parent,
1269			 "Spurious VME interrupt, level:%x, vector:%x\n", level,
1270			 statid);
1271}
1272EXPORT_SYMBOL(vme_irq_handler);
1273
1274/**
1275 * vme_irq_request - Request a specific VME interrupt.
1276 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
1277 * @level: Interrupt priority being requested.
1278 * @statid: Interrupt vector being requested.
1279 * @callback: Pointer to callback function called when VME interrupt/vector
1280 *            received.
1281 * @priv_data: Generic pointer that will be passed to the callback function.
1282 *
1283 * Request callback to be attached as a handler for VME interrupts with provided
1284 * level and statid.
1285 *
1286 * Return: Zero on success, -EINVAL on invalid vme device, level or if the
1287 *         function is not supported, -EBUSY if the level/statid combination is
1288 *         already in use. Hardware specific errors also possible.
1289 */
1290int vme_irq_request(struct vme_dev *vdev, int level, int statid,
1291		    void (*callback)(int, int, void *),
1292		    void *priv_data)
1293{
1294	struct vme_bridge *bridge;
1295
1296	bridge = vdev->bridge;
1297	if (!bridge) {
1298		dev_err(&vdev->dev, "Can't find VME bus\n");
1299		return -EINVAL;
1300	}
1301
1302	if ((level < 1) || (level > 7)) {
1303		dev_err(bridge->parent, "Invalid interrupt level\n");
1304		return -EINVAL;
1305	}
1306
1307	if (!bridge->irq_set) {
1308		dev_err(bridge->parent,
1309			"Configuring interrupts not supported\n");
1310		return -EINVAL;
1311	}
1312
1313	mutex_lock(&bridge->irq_mtx);
1314
1315	if (bridge->irq[level - 1].callback[statid].func) {
1316		mutex_unlock(&bridge->irq_mtx);
1317		dev_warn(bridge->parent, "VME Interrupt already taken\n");
1318		return -EBUSY;
1319	}
1320
1321	bridge->irq[level - 1].count++;
1322	bridge->irq[level - 1].callback[statid].priv_data = priv_data;
1323	bridge->irq[level - 1].callback[statid].func = callback;
1324
1325	/* Enable IRQ level */
1326	bridge->irq_set(bridge, level, 1, 1);
1327
1328	mutex_unlock(&bridge->irq_mtx);
1329
1330	return 0;
1331}
1332EXPORT_SYMBOL(vme_irq_request);
1333
1334/**
1335 * vme_irq_free - Free a VME interrupt.
1336 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
1337 * @level: Interrupt priority of interrupt being freed.
1338 * @statid: Interrupt vector of interrupt being freed.
1339 *
1340 * Remove previously attached callback from VME interrupt priority/vector.
1341 */
1342void vme_irq_free(struct vme_dev *vdev, int level, int statid)
1343{
1344	struct vme_bridge *bridge;
1345
1346	bridge = vdev->bridge;
1347	if (!bridge) {
1348		dev_err(&vdev->dev, "Can't find VME bus\n");
1349		return;
1350	}
1351
1352	if ((level < 1) || (level > 7)) {
1353		dev_err(bridge->parent, "Invalid interrupt level\n");
1354		return;
1355	}
1356
1357	if (!bridge->irq_set) {
1358		dev_err(bridge->parent,
1359			"Configuring interrupts not supported\n");
1360		return;
1361	}
1362
1363	mutex_lock(&bridge->irq_mtx);
1364
1365	bridge->irq[level - 1].count--;
1366
1367	/* Disable IRQ level if no more interrupts attached at this level*/
1368	if (bridge->irq[level - 1].count == 0)
1369		bridge->irq_set(bridge, level, 0, 1);
1370
1371	bridge->irq[level - 1].callback[statid].func = NULL;
1372	bridge->irq[level - 1].callback[statid].priv_data = NULL;
1373
1374	mutex_unlock(&bridge->irq_mtx);
1375}
1376EXPORT_SYMBOL(vme_irq_free);
1377
1378/**
1379 * vme_irq_generate - Generate VME interrupt.
1380 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
1381 * @level: Interrupt priority at which to assert the interrupt.
1382 * @statid: Interrupt vector to associate with the interrupt.
1383 *
1384 * Generate a VME interrupt of the provided level and with the provided
1385 * statid.
1386 *
1387 * Return: Zero on success, -EINVAL on invalid vme device, level or if the
1388 *         function is not supported. Hardware specific errors also possible.
1389 */
1390int vme_irq_generate(struct vme_dev *vdev, int level, int statid)
1391{
1392	struct vme_bridge *bridge;
1393
1394	bridge = vdev->bridge;
1395	if (!bridge) {
1396		dev_err(&vdev->dev, "Can't find VME bus\n");
1397		return -EINVAL;
1398	}
1399
1400	if ((level < 1) || (level > 7)) {
1401		dev_warn(bridge->parent, "Invalid interrupt level\n");
1402		return -EINVAL;
1403	}
1404
1405	if (!bridge->irq_generate) {
1406		dev_warn(bridge->parent,
1407			 "Interrupt generation not supported\n");
1408		return -EINVAL;
1409	}
1410
1411	return bridge->irq_generate(bridge, level, statid);
1412}
1413EXPORT_SYMBOL(vme_irq_generate);
1414
1415/**
1416 * vme_lm_request - Request a VME location monitor
1417 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
1418 *
1419 * Allocate a location monitor resource to the driver. A location monitor
1420 * allows the driver to monitor accesses to a contiguous number of
1421 * addresses on the VME bus.
1422 *
1423 * Return: Pointer to a VME resource on success or NULL on failure.
1424 */
1425struct vme_resource *vme_lm_request(struct vme_dev *vdev)
1426{
1427	struct vme_bridge *bridge;
1428	struct vme_lm_resource *allocated_lm = NULL;
1429	struct vme_lm_resource *lm = NULL;
1430	struct vme_resource *resource = NULL;
1431
1432	bridge = vdev->bridge;
1433	if (!bridge) {
1434		dev_err(&vdev->dev, "Can't find VME bus\n");
1435		goto err_bus;
1436	}
1437
1438	/* Loop through LM resources */
1439	list_for_each_entry(lm, &bridge->lm_resources, list) {
1440		if (!lm) {
1441			dev_err(bridge->parent,
1442				"Registered NULL Location Monitor resource\n");
1443			continue;
1444		}
1445
1446		/* Find an unlocked controller */
1447		mutex_lock(&lm->mtx);
1448		if (lm->locked == 0) {
1449			lm->locked = 1;
1450			mutex_unlock(&lm->mtx);
1451			allocated_lm = lm;
1452			break;
1453		}
1454		mutex_unlock(&lm->mtx);
1455	}
1456
1457	/* Check to see if we found a resource */
1458	if (!allocated_lm)
1459		goto err_lm;
1460
1461	resource = kmalloc(sizeof(*resource), GFP_KERNEL);
1462	if (!resource)
1463		goto err_alloc;
1464
1465	resource->type = VME_LM;
1466	resource->entry = &allocated_lm->list;
1467
1468	return resource;
1469
1470err_alloc:
1471	/* Unlock image */
1472	mutex_lock(&lm->mtx);
1473	lm->locked = 0;
1474	mutex_unlock(&lm->mtx);
1475err_lm:
1476err_bus:
1477	return NULL;
1478}
1479EXPORT_SYMBOL(vme_lm_request);
1480
1481/**
1482 * vme_lm_count - Determine number of VME Addresses monitored
1483 * @resource: Pointer to VME location monitor resource.
1484 *
1485 * The number of contiguous addresses monitored is hardware dependent.
1486 * Return the number of contiguous addresses monitored by the
1487 * location monitor.
1488 *
1489 * Return: Count of addresses monitored or -EINVAL when provided with an
1490 *	   invalid location monitor resource.
1491 */
1492int vme_lm_count(struct vme_resource *resource)
1493{
1494	struct vme_bridge *bridge = find_bridge(resource);
1495	struct vme_lm_resource *lm;
1496
1497	if (resource->type != VME_LM) {
1498		dev_err(bridge->parent, "Not a Location Monitor resource\n");
1499		return -EINVAL;
1500	}
1501
1502	lm = list_entry(resource->entry, struct vme_lm_resource, list);
1503
1504	return lm->monitors;
1505}
1506EXPORT_SYMBOL(vme_lm_count);
1507
1508/**
1509 * vme_lm_set - Configure location monitor
1510 * @resource: Pointer to VME location monitor resource.
1511 * @lm_base: Base address to monitor.
1512 * @aspace: VME address space to monitor.
1513 * @cycle: VME bus cycle type to monitor.
1514 *
1515 * Set the base address, address space and cycle type of accesses to be
1516 * monitored by the location monitor.
1517 *
1518 * Return: Zero on success, -EINVAL when provided with an invalid location
1519 *	   monitor resource or function is not supported. Hardware specific
1520 *	   errors may also be returned.
1521 */
1522int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base,
1523	       u32 aspace, u32 cycle)
1524{
1525	struct vme_bridge *bridge = find_bridge(resource);
1526	struct vme_lm_resource *lm;
1527
1528	if (resource->type != VME_LM) {
1529		dev_err(bridge->parent, "Not a Location Monitor resource\n");
1530		return -EINVAL;
1531	}
1532
1533	lm = list_entry(resource->entry, struct vme_lm_resource, list);
1534
1535	if (!bridge->lm_set) {
1536		dev_err(bridge->parent, "%s not supported\n", __func__);
1537		return -EINVAL;
1538	}
1539
1540	return bridge->lm_set(lm, lm_base, aspace, cycle);
1541}
1542EXPORT_SYMBOL(vme_lm_set);
1543
1544/**
1545 * vme_lm_get - Retrieve location monitor settings
1546 * @resource: Pointer to VME location monitor resource.
1547 * @lm_base: Pointer used to output the base address monitored.
1548 * @aspace: Pointer used to output the address space monitored.
1549 * @cycle: Pointer used to output the VME bus cycle type monitored.
1550 *
1551 * Retrieve the base address, address space and cycle type of accesses to
1552 * be monitored by the location monitor.
1553 *
1554 * Return: Zero on success, -EINVAL when provided with an invalid location
1555 *	   monitor resource or function is not supported. Hardware specific
1556 *	   errors may also be returned.
1557 */
1558int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base,
1559	       u32 *aspace, u32 *cycle)
1560{
1561	struct vme_bridge *bridge = find_bridge(resource);
1562	struct vme_lm_resource *lm;
1563
1564	if (resource->type != VME_LM) {
1565		dev_err(bridge->parent, "Not a Location Monitor resource\n");
1566		return -EINVAL;
1567	}
1568
1569	lm = list_entry(resource->entry, struct vme_lm_resource, list);
1570
1571	if (!bridge->lm_get) {
1572		dev_err(bridge->parent, "%s not supported\n", __func__);
1573		return -EINVAL;
1574	}
1575
1576	return bridge->lm_get(lm, lm_base, aspace, cycle);
1577}
1578EXPORT_SYMBOL(vme_lm_get);
1579
1580/**
1581 * vme_lm_attach - Provide callback for location monitor address
1582 * @resource: Pointer to VME location monitor resource.
1583 * @monitor: Offset to which callback should be attached.
1584 * @callback: Pointer to callback function called when triggered.
1585 * @data: Generic pointer that will be passed to the callback function.
1586 *
1587 * Attach a callback to the specified offset into the location monitors
1588 * monitored addresses. A generic pointer is provided to allow data to be
1589 * passed to the callback when called.
1590 *
1591 * Return: Zero on success, -EINVAL when provided with an invalid location
1592 *	   monitor resource or function is not supported. Hardware specific
1593 *	   errors may also be returned.
1594 */
1595int vme_lm_attach(struct vme_resource *resource, int monitor,
1596		  void (*callback)(void *), void *data)
1597{
1598	struct vme_bridge *bridge = find_bridge(resource);
1599	struct vme_lm_resource *lm;
1600
1601	if (resource->type != VME_LM) {
1602		dev_err(bridge->parent, "Not a Location Monitor resource\n");
1603		return -EINVAL;
1604	}
1605
1606	lm = list_entry(resource->entry, struct vme_lm_resource, list);
1607
1608	if (!bridge->lm_attach) {
1609		dev_err(bridge->parent, "%s not supported\n", __func__);
1610		return -EINVAL;
1611	}
1612
1613	return bridge->lm_attach(lm, monitor, callback, data);
1614}
1615EXPORT_SYMBOL(vme_lm_attach);
1616
1617/**
1618 * vme_lm_detach - Remove callback for location monitor address
1619 * @resource: Pointer to VME location monitor resource.
1620 * @monitor: Offset to which callback should be removed.
1621 *
1622 * Remove the callback associated with the specified offset into the
1623 * location monitors monitored addresses.
1624 *
1625 * Return: Zero on success, -EINVAL when provided with an invalid location
1626 *	   monitor resource or function is not supported. Hardware specific
1627 *	   errors may also be returned.
1628 */
1629int vme_lm_detach(struct vme_resource *resource, int monitor)
1630{
1631	struct vme_bridge *bridge = find_bridge(resource);
1632	struct vme_lm_resource *lm;
1633
1634	if (resource->type != VME_LM) {
1635		dev_err(bridge->parent, "Not a Location Monitor resource\n");
1636		return -EINVAL;
1637	}
1638
1639	lm = list_entry(resource->entry, struct vme_lm_resource, list);
1640
1641	if (!bridge->lm_detach) {
1642		dev_err(bridge->parent, "%s not supported\n", __func__);
1643		return -EINVAL;
1644	}
1645
1646	return bridge->lm_detach(lm, monitor);
1647}
1648EXPORT_SYMBOL(vme_lm_detach);
1649
1650/**
1651 * vme_lm_free - Free allocated VME location monitor
1652 * @resource: Pointer to VME location monitor resource.
1653 *
1654 * Free allocation of a VME location monitor.
1655 *
1656 * WARNING: This function currently expects that any callbacks that have
1657 *          been attached to the location monitor have been removed.
1658 *
1659 * Return: Zero on success, -EINVAL when provided with an invalid location
1660 *	   monitor resource.
1661 */
1662void vme_lm_free(struct vme_resource *resource)
1663{
1664	struct vme_bridge *bridge = find_bridge(resource);
1665	struct vme_lm_resource *lm;
1666
1667	if (resource->type != VME_LM) {
1668		dev_err(bridge->parent, "Not a Location Monitor resource\n");
1669		return;
1670	}
1671
1672	lm = list_entry(resource->entry, struct vme_lm_resource, list);
1673
1674	mutex_lock(&lm->mtx);
1675
1676	/* XXX
1677	 * Check to see that there aren't any callbacks still attached, if
1678	 * there are we should probably be detaching them!
1679	 */
1680
1681	lm->locked = 0;
1682
1683	mutex_unlock(&lm->mtx);
1684
1685	kfree(resource);
1686}
1687EXPORT_SYMBOL(vme_lm_free);
1688
1689/**
1690 * vme_slot_num - Retrieve slot ID
1691 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
1692 *
1693 * Retrieve the slot ID associated with the provided VME device.
1694 *
1695 * Return: The slot ID on success, -EINVAL if VME bridge cannot be determined
1696 *         or the function is not supported. Hardware specific errors may also
1697 *         be returned.
1698 */
1699int vme_slot_num(struct vme_dev *vdev)
1700{
1701	struct vme_bridge *bridge;
1702
1703	bridge = vdev->bridge;
1704	if (!bridge) {
1705		dev_err(&vdev->dev, "Can't find VME bus\n");
1706		return -EINVAL;
1707	}
1708
1709	if (!bridge->slot_get) {
1710		dev_warn(bridge->parent, "%s not supported\n", __func__);
1711		return -EINVAL;
1712	}
1713
1714	return bridge->slot_get(bridge);
1715}
1716EXPORT_SYMBOL(vme_slot_num);
1717
1718/**
1719 * vme_bus_num - Retrieve bus number
1720 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
1721 *
1722 * Retrieve the bus enumeration associated with the provided VME device.
1723 *
1724 * Return: The bus number on success, -EINVAL if VME bridge cannot be
1725 *         determined.
1726 */
1727int vme_bus_num(struct vme_dev *vdev)
1728{
1729	struct vme_bridge *bridge;
1730
1731	bridge = vdev->bridge;
1732	if (!bridge) {
1733		dev_err(&vdev->dev, "Can't find VME bus\n");
1734		return -EINVAL;
1735	}
1736
1737	return bridge->num;
1738}
1739EXPORT_SYMBOL(vme_bus_num);
1740
1741/* - Bridge Registration --------------------------------------------------- */
1742
1743static void vme_dev_release(struct device *dev)
1744{
1745	kfree(dev_to_vme_dev(dev));
1746}
1747
1748/* Common bridge initialization */
1749struct vme_bridge *vme_init_bridge(struct vme_bridge *bridge)
1750{
1751	INIT_LIST_HEAD(&bridge->vme_error_handlers);
1752	INIT_LIST_HEAD(&bridge->master_resources);
1753	INIT_LIST_HEAD(&bridge->slave_resources);
1754	INIT_LIST_HEAD(&bridge->dma_resources);
1755	INIT_LIST_HEAD(&bridge->lm_resources);
1756	mutex_init(&bridge->irq_mtx);
1757
1758	return bridge;
1759}
1760EXPORT_SYMBOL(vme_init_bridge);
1761
1762int vme_register_bridge(struct vme_bridge *bridge)
1763{
1764	int i;
1765	int ret = -1;
1766
1767	mutex_lock(&vme_buses_lock);
1768	for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) {
1769		if ((vme_bus_numbers & (1 << i)) == 0) {
1770			vme_bus_numbers |= (1 << i);
1771			bridge->num = i;
1772			INIT_LIST_HEAD(&bridge->devices);
1773			list_add_tail(&bridge->bus_list, &vme_bus_list);
1774			ret = 0;
1775			break;
1776		}
1777	}
1778	mutex_unlock(&vme_buses_lock);
1779
1780	return ret;
1781}
1782EXPORT_SYMBOL(vme_register_bridge);
1783
1784void vme_unregister_bridge(struct vme_bridge *bridge)
1785{
1786	struct vme_dev *vdev;
1787	struct vme_dev *tmp;
1788
1789	mutex_lock(&vme_buses_lock);
1790	vme_bus_numbers &= ~(1 << bridge->num);
1791	list_for_each_entry_safe(vdev, tmp, &bridge->devices, bridge_list) {
1792		list_del(&vdev->drv_list);
1793		list_del(&vdev->bridge_list);
1794		device_unregister(&vdev->dev);
1795	}
1796	list_del(&bridge->bus_list);
1797	mutex_unlock(&vme_buses_lock);
1798}
1799EXPORT_SYMBOL(vme_unregister_bridge);
1800
1801/* - Driver Registration --------------------------------------------------- */
1802
1803static int __vme_register_driver_bus(struct vme_driver *drv,
1804				     struct vme_bridge *bridge,
1805				     unsigned int ndevs)
1806{
1807	int err;
1808	unsigned int i;
1809	struct vme_dev *vdev;
1810	struct vme_dev *tmp;
1811
1812	for (i = 0; i < ndevs; i++) {
1813		vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
1814		if (!vdev) {
1815			err = -ENOMEM;
1816			goto err_devalloc;
1817		}
1818		vdev->num = i;
1819		vdev->bridge = bridge;
1820		vdev->dev.platform_data = drv;
1821		vdev->dev.release = vme_dev_release;
1822		vdev->dev.parent = bridge->parent;
1823		vdev->dev.bus = &vme_bus_type;
1824		dev_set_name(&vdev->dev, "%s.%u-%u", drv->name, bridge->num,
1825			     vdev->num);
1826
1827		err = device_register(&vdev->dev);
1828		if (err)
1829			goto err_reg;
1830
1831		if (vdev->dev.platform_data) {
1832			list_add_tail(&vdev->drv_list, &drv->devices);
1833			list_add_tail(&vdev->bridge_list, &bridge->devices);
1834		} else {
1835			device_unregister(&vdev->dev);
1836		}
1837	}
1838	return 0;
1839
1840err_reg:
1841	put_device(&vdev->dev);
1842err_devalloc:
1843	list_for_each_entry_safe(vdev, tmp, &drv->devices, drv_list) {
1844		list_del(&vdev->drv_list);
1845		list_del(&vdev->bridge_list);
1846		device_unregister(&vdev->dev);
1847	}
1848	return err;
1849}
1850
1851static int __vme_register_driver(struct vme_driver *drv, unsigned int ndevs)
1852{
1853	struct vme_bridge *bridge;
1854	int err = 0;
1855
1856	mutex_lock(&vme_buses_lock);
1857	list_for_each_entry(bridge, &vme_bus_list, bus_list) {
1858		/*
1859		 * This cannot cause trouble as we already have vme_buses_lock
1860		 * and if the bridge is removed, it will have to go through
1861		 * vme_unregister_bridge() to do it (which calls remove() on
1862		 * the bridge which in turn tries to acquire vme_buses_lock and
1863		 * will have to wait).
1864		 */
1865		err = __vme_register_driver_bus(drv, bridge, ndevs);
1866		if (err)
1867			break;
1868	}
1869	mutex_unlock(&vme_buses_lock);
1870	return err;
1871}
1872
1873/**
1874 * vme_register_driver - Register a VME driver
1875 * @drv: Pointer to VME driver structure to register.
1876 * @ndevs: Maximum number of devices to allow to be enumerated.
1877 *
1878 * Register a VME device driver with the VME subsystem.
1879 *
1880 * Return: Zero on success, error value on registration failure.
1881 */
1882int vme_register_driver(struct vme_driver *drv, unsigned int ndevs)
1883{
1884	int err;
1885
1886	drv->driver.name = drv->name;
1887	drv->driver.bus = &vme_bus_type;
1888	INIT_LIST_HEAD(&drv->devices);
1889
1890	err = driver_register(&drv->driver);
1891	if (err)
1892		return err;
1893
1894	err = __vme_register_driver(drv, ndevs);
1895	if (err)
1896		driver_unregister(&drv->driver);
1897
1898	return err;
1899}
1900EXPORT_SYMBOL(vme_register_driver);
1901
1902/**
1903 * vme_unregister_driver - Unregister a VME driver
1904 * @drv: Pointer to VME driver structure to unregister.
1905 *
1906 * Unregister a VME device driver from the VME subsystem.
1907 */
1908void vme_unregister_driver(struct vme_driver *drv)
1909{
1910	struct vme_dev *dev, *dev_tmp;
1911
1912	mutex_lock(&vme_buses_lock);
1913	list_for_each_entry_safe(dev, dev_tmp, &drv->devices, drv_list) {
1914		list_del(&dev->drv_list);
1915		list_del(&dev->bridge_list);
1916		device_unregister(&dev->dev);
1917	}
1918	mutex_unlock(&vme_buses_lock);
1919
1920	driver_unregister(&drv->driver);
1921}
1922EXPORT_SYMBOL(vme_unregister_driver);
1923
1924/* - Bus Registration ------------------------------------------------------ */
1925
1926static int vme_bus_match(struct device *dev, const struct device_driver *drv)
1927{
1928	const struct vme_driver *vme_drv;
1929
1930	vme_drv = container_of(drv, struct vme_driver, driver);
1931
1932	if (dev->platform_data == vme_drv) {
1933		struct vme_dev *vdev = dev_to_vme_dev(dev);
1934
1935		if (vme_drv->match && vme_drv->match(vdev))
1936			return 1;
1937
1938		dev->platform_data = NULL;
1939	}
1940	return 0;
1941}
1942
1943static int vme_bus_probe(struct device *dev)
1944{
1945	struct vme_driver *driver;
1946	struct vme_dev *vdev = dev_to_vme_dev(dev);
1947
1948	driver = dev->platform_data;
1949	if (driver->probe)
1950		return driver->probe(vdev);
1951
1952	return -ENODEV;
1953}
1954
1955static void vme_bus_remove(struct device *dev)
1956{
1957	struct vme_driver *driver;
1958	struct vme_dev *vdev = dev_to_vme_dev(dev);
1959
1960	driver = dev->platform_data;
1961	if (driver->remove)
1962		driver->remove(vdev);
1963}
1964
1965const struct bus_type vme_bus_type = {
1966	.name = "vme",
1967	.match = vme_bus_match,
1968	.probe = vme_bus_probe,
1969	.remove = vme_bus_remove,
1970};
1971EXPORT_SYMBOL(vme_bus_type);
1972
1973static int __init vme_init(void)
1974{
1975	return bus_register(&vme_bus_type);
1976}
1977subsys_initcall(vme_init);
~/ Read-only file preview.