linux/drivers/staging/vme/vme.c
<<
>>
Prefs
   1/*
   2 * VME Bridge Framework
   3 *
   4 * Author: Martyn Welch <martyn.welch@gefanuc.com>
   5 * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
   6 *
   7 * Based on work by Tom Armistead and Ajit Prem
   8 * Copyright 2004 Motorola Inc.
   9 *
  10 * This program is free software; you can redistribute  it and/or modify it
  11 * under  the terms of  the GNU General  Public License as published by the
  12 * Free Software Foundation;  either version 2 of the  License, or (at your
  13 * option) any later version.
  14 */
  15
  16#include <linux/version.h>
  17#include <linux/module.h>
  18#include <linux/moduleparam.h>
  19#include <linux/mm.h>
  20#include <linux/types.h>
  21#include <linux/kernel.h>
  22#include <linux/errno.h>
  23#include <linux/pci.h>
  24#include <linux/poll.h>
  25#include <linux/highmem.h>
  26#include <linux/interrupt.h>
  27#include <linux/pagemap.h>
  28#include <linux/device.h>
  29#include <linux/dma-mapping.h>
  30#include <linux/syscalls.h>
  31#include <linux/mutex.h>
  32#include <linux/spinlock.h>
  33
  34#include "vme.h"
  35#include "vme_bridge.h"
  36
  37/* Bitmask and mutex to keep track of bridge numbers */
  38static unsigned int vme_bus_numbers;
  39DEFINE_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("No resource\n");
  98                return NULL;
  99        }
 100
 101        bridge = find_bridge(resource);
 102        if(bridge == NULL) {
 103                printk("Can't find bridge\n");
 104                return NULL;
 105        }
 106
 107        /* Find pci_dev container of dev */
 108        if (bridge->parent == NULL) {
 109                printk("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("No resource\n");
 132                return;
 133        }
 134
 135        bridge = find_bridge(resource);
 136        if(bridge == NULL) {
 137                printk("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("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("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("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("Function not supported\n");
 313                return -ENOSYS;
 314        }
 315
 316        if(!(((image->address_attr & aspace) == aspace) &&
 317                ((image->cycle_attr & cycle) == cycle))) {
 318                printk("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("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("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("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("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
 444        kfree(resource);
 445err_alloc:
 446        /* Unlock image */
 447        spin_lock(&(master_image->lock));
 448        master_image->locked = 0;
 449        spin_unlock(&(master_image->lock));
 450err_image:
 451err_bus:
 452        return NULL;
 453}
 454EXPORT_SYMBOL(vme_master_request);
 455
 456int vme_master_set (struct vme_resource *resource, int enabled,
 457        unsigned long long vme_base, unsigned long long size,
 458        vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
 459{
 460        struct vme_bridge *bridge = find_bridge(resource);
 461        struct vme_master_resource *image;
 462        int retval;
 463
 464        if (resource->type != VME_MASTER) {
 465                printk("Not a master resource\n");
 466                return -EINVAL;
 467        }
 468
 469        image = list_entry(resource->entry, struct vme_master_resource, list);
 470
 471        if (bridge->master_set == NULL) {
 472                printk("vme_master_set not supported\n");
 473                return -EINVAL;
 474        }
 475
 476        if(!(((image->address_attr & aspace) == aspace) &&
 477                ((image->cycle_attr & cycle) == cycle) &&
 478                ((image->width_attr & dwidth) == dwidth))) {
 479                printk("Invalid attributes\n");
 480                return -EINVAL;
 481        }
 482
 483        retval = vme_check_window(aspace, vme_base, size);
 484        if(retval)
 485                return retval;
 486
 487        return bridge->master_set(image, enabled, vme_base, size, aspace,
 488                cycle, dwidth);
 489}
 490EXPORT_SYMBOL(vme_master_set);
 491
 492int vme_master_get (struct vme_resource *resource, int *enabled,
 493        unsigned long long *vme_base, unsigned long long *size,
 494        vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
 495{
 496        struct vme_bridge *bridge = find_bridge(resource);
 497        struct vme_master_resource *image;
 498
 499        if (resource->type != VME_MASTER) {
 500                printk("Not a master resource\n");
 501                return -EINVAL;
 502        }
 503
 504        image = list_entry(resource->entry, struct vme_master_resource, list);
 505
 506        if (bridge->master_get == NULL) {
 507                printk("vme_master_set not supported\n");
 508                return -EINVAL;
 509        }
 510
 511        return bridge->master_get(image, enabled, vme_base, size, aspace,
 512                cycle, dwidth);
 513}
 514EXPORT_SYMBOL(vme_master_get);
 515
 516/*
 517 * Read data out of VME space into a buffer.
 518 */
 519ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count,
 520        loff_t offset)
 521{
 522        struct vme_bridge *bridge = find_bridge(resource);
 523        struct vme_master_resource *image;
 524        size_t length;
 525
 526        if (bridge->master_read == NULL) {
 527                printk("Reading from resource not supported\n");
 528                return -EINVAL;
 529        }
 530
 531        if (resource->type != VME_MASTER) {
 532                printk("Not a master resource\n");
 533                return -EINVAL;
 534        }
 535
 536        image = list_entry(resource->entry, struct vme_master_resource, list);
 537
 538        length = vme_get_size(resource);
 539
 540        if (offset > length) {
 541                printk("Invalid Offset\n");
 542                return -EFAULT;
 543        }
 544
 545        if ((offset + count) > length)
 546                count = length - offset;
 547
 548        return bridge->master_read(image, buf, count, offset);
 549
 550}
 551EXPORT_SYMBOL(vme_master_read);
 552
 553/*
 554 * Write data out to VME space from a buffer.
 555 */
 556ssize_t vme_master_write (struct vme_resource *resource, void *buf,
 557        size_t count, loff_t offset)
 558{
 559        struct vme_bridge *bridge = find_bridge(resource);
 560        struct vme_master_resource *image;
 561        size_t length;
 562
 563        if (bridge->master_write == NULL) {
 564                printk("Writing to resource not supported\n");
 565                return -EINVAL;
 566        }
 567
 568        if (resource->type != VME_MASTER) {
 569                printk("Not a master resource\n");
 570                return -EINVAL;
 571        }
 572
 573        image = list_entry(resource->entry, struct vme_master_resource, list);
 574
 575        length = vme_get_size(resource);
 576
 577        if (offset > length) {
 578                printk("Invalid Offset\n");
 579                return -EFAULT;
 580        }
 581
 582        if ((offset + count) > length)
 583                count = length - offset;
 584
 585        return bridge->master_write(image, buf, count, offset);
 586}
 587EXPORT_SYMBOL(vme_master_write);
 588
 589/*
 590 * Perform RMW cycle to provided location.
 591 */
 592unsigned int vme_master_rmw (struct vme_resource *resource, unsigned int mask,
 593        unsigned int compare, unsigned int swap, loff_t offset)
 594{
 595        struct vme_bridge *bridge = find_bridge(resource);
 596        struct vme_master_resource *image;
 597
 598        if (bridge->master_rmw == NULL) {
 599                printk("Writing to resource not supported\n");
 600                return -EINVAL;
 601        }
 602
 603        if (resource->type != VME_MASTER) {
 604                printk("Not a master resource\n");
 605                return -EINVAL;
 606        }
 607
 608        image = list_entry(resource->entry, struct vme_master_resource, list);
 609
 610        return bridge->master_rmw(image, mask, compare, swap, offset);
 611}
 612EXPORT_SYMBOL(vme_master_rmw);
 613
 614void vme_master_free(struct vme_resource *resource)
 615{
 616        struct vme_master_resource *master_image;
 617
 618        if (resource->type != VME_MASTER) {
 619                printk("Not a master resource\n");
 620                return;
 621        }
 622
 623        master_image = list_entry(resource->entry, struct vme_master_resource,
 624                list);
 625        if (master_image == NULL) {
 626                printk("Can't find master resource\n");
 627                return;
 628        }
 629
 630        /* Unlock image */
 631        spin_lock(&(master_image->lock));
 632        if (master_image->locked == 0)
 633                printk(KERN_ERR "Image is already free\n");
 634
 635        master_image->locked = 0;
 636        spin_unlock(&(master_image->lock));
 637
 638        /* Free up resource memory */
 639        kfree(resource);
 640}
 641EXPORT_SYMBOL(vme_master_free);
 642
 643/*
 644 * Request a DMA controller with specific attributes, return some unique
 645 * identifier.
 646 */
 647struct vme_resource *vme_request_dma(struct device *dev)
 648{
 649        struct vme_bridge *bridge;
 650        struct list_head *dma_pos = NULL;
 651        struct vme_dma_resource *allocated_ctrlr = NULL;
 652        struct vme_dma_resource *dma_ctrlr = NULL;
 653        struct vme_resource *resource = NULL;
 654
 655        /* XXX Not checking resource attributes */
 656        printk(KERN_ERR "No VME resource Attribute tests done\n");
 657
 658        bridge = dev_to_bridge(dev);
 659        if (bridge == NULL) {
 660                printk(KERN_ERR "Can't find VME bus\n");
 661                goto err_bus;
 662        }
 663
 664        /* Loop through DMA resources */
 665        list_for_each(dma_pos, &(bridge->dma_resources)) {
 666                dma_ctrlr = list_entry(dma_pos,
 667                        struct vme_dma_resource, list);
 668
 669                if (dma_ctrlr == NULL) {
 670                        printk("Registered NULL DMA resource\n");
 671                        continue;
 672                }
 673
 674                /* Find an unlocked controller */
 675                mutex_lock(&(dma_ctrlr->mtx));
 676                if(dma_ctrlr->locked == 0) {
 677                        dma_ctrlr->locked = 1;
 678                        mutex_unlock(&(dma_ctrlr->mtx));
 679                        allocated_ctrlr = dma_ctrlr;
 680                        break;
 681                }
 682                mutex_unlock(&(dma_ctrlr->mtx));
 683        }
 684
 685        /* Check to see if we found a resource */
 686        if (allocated_ctrlr == NULL)
 687                goto err_ctrlr;
 688
 689        resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
 690        if (resource == NULL) {
 691                printk(KERN_WARNING "Unable to allocate resource structure\n");
 692                goto err_alloc;
 693        }
 694        resource->type = VME_DMA;
 695        resource->entry = &(allocated_ctrlr->list);
 696
 697        return resource;
 698
 699err_alloc:
 700        /* Unlock image */
 701        mutex_lock(&(dma_ctrlr->mtx));
 702        dma_ctrlr->locked = 0;
 703        mutex_unlock(&(dma_ctrlr->mtx));
 704err_ctrlr:
 705err_bus:
 706        return NULL;
 707}
 708EXPORT_SYMBOL(vme_request_dma);
 709
 710/*
 711 * Start new list
 712 */
 713struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource)
 714{
 715        struct vme_dma_resource *ctrlr;
 716        struct vme_dma_list *dma_list;
 717
 718        if (resource->type != VME_DMA) {
 719                printk("Not a DMA resource\n");
 720                return NULL;
 721        }
 722
 723        ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
 724
 725        dma_list = (struct vme_dma_list *)kmalloc(
 726                sizeof(struct vme_dma_list), GFP_KERNEL);
 727        if(dma_list == NULL) {
 728                printk("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 = (struct vme_dma_attr *)kmalloc(
 749                sizeof(struct vme_dma_attr), GFP_KERNEL);
 750        if(attributes == NULL) {
 751                printk("Unable to allocate memory for attributes structure\n");
 752                goto err_attr;
 753        }
 754
 755        pattern_attr = (struct vme_dma_pattern *)kmalloc(
 756                sizeof(struct vme_dma_pattern), GFP_KERNEL);
 757        if(pattern_attr == NULL) {
 758                printk("Unable to allocate memory for pattern 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
 770        kfree(pattern_attr);
 771err_pat:
 772        kfree(attributes);
 773err_attr:
 774        return NULL;
 775}
 776EXPORT_SYMBOL(vme_dma_pattern_attribute);
 777
 778/*
 779 * Create "PCI" type attributes
 780 */
 781struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address)
 782{
 783        struct vme_dma_attr *attributes;
 784        struct vme_dma_pci *pci_attr;
 785
 786        /* XXX Run some sanity checks here */
 787
 788        attributes = (struct vme_dma_attr *)kmalloc(
 789                sizeof(struct vme_dma_attr), GFP_KERNEL);
 790        if(attributes == NULL) {
 791                printk("Unable to allocate memory for attributes structure\n");
 792                goto err_attr;
 793        }
 794
 795        pci_attr = (struct vme_dma_pci *)kmalloc(sizeof(struct vme_dma_pci),
 796                GFP_KERNEL);
 797        if(pci_attr == NULL) {
 798                printk("Unable to allocate memory for pci attributes\n");
 799                goto err_pci;
 800        }
 801
 802
 803
 804        attributes->type = VME_DMA_PCI;
 805        attributes->private = (void *)pci_attr;
 806
 807        pci_attr->address = address;
 808
 809        return attributes;
 810
 811        kfree(pci_attr);
 812err_pci:
 813        kfree(attributes);
 814err_attr:
 815        return NULL;
 816}
 817EXPORT_SYMBOL(vme_dma_pci_attribute);
 818
 819/*
 820 * Create "VME" type attributes
 821 */
 822struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address,
 823        vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
 824{
 825        struct vme_dma_attr *attributes;
 826        struct vme_dma_vme *vme_attr;
 827
 828        /* XXX Run some sanity checks here */
 829
 830        attributes = (struct vme_dma_attr *)kmalloc(
 831                sizeof(struct vme_dma_attr), GFP_KERNEL);
 832        if(attributes == NULL) {
 833                printk("Unable to allocate memory for attributes structure\n");
 834                goto err_attr;
 835        }
 836
 837        vme_attr = (struct vme_dma_vme *)kmalloc(sizeof(struct vme_dma_vme),
 838                GFP_KERNEL);
 839        if(vme_attr == NULL) {
 840                printk("Unable to allocate memory for vme attributes\n");
 841                goto err_vme;
 842        }
 843
 844        attributes->type = VME_DMA_VME;
 845        attributes->private = (void *)vme_attr;
 846
 847        vme_attr->address = address;
 848        vme_attr->aspace = aspace;
 849        vme_attr->cycle = cycle;
 850        vme_attr->dwidth = dwidth;
 851
 852        return attributes;
 853
 854        kfree(vme_attr);
 855err_vme:
 856        kfree(attributes);
 857err_attr:
 858        return NULL;
 859}
 860EXPORT_SYMBOL(vme_dma_vme_attribute);
 861
 862/*
 863 * Free attribute
 864 */
 865void vme_dma_free_attribute(struct vme_dma_attr *attributes)
 866{
 867        kfree(attributes->private);
 868        kfree(attributes);
 869}
 870EXPORT_SYMBOL(vme_dma_free_attribute);
 871
 872int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
 873        struct vme_dma_attr *dest, size_t count)
 874{
 875        struct vme_bridge *bridge = list->parent->parent;
 876        int retval;
 877
 878        if (bridge->dma_list_add == NULL) {
 879                printk("Link List DMA generation not supported\n");
 880                return -EINVAL;
 881        }
 882
 883        if (mutex_trylock(&(list->mtx))) {
 884                printk("Link List already submitted\n");
 885                return -EINVAL;
 886        }
 887
 888        retval = bridge->dma_list_add(list, src, dest, count);
 889
 890        mutex_unlock(&(list->mtx));
 891
 892        return retval;
 893}
 894EXPORT_SYMBOL(vme_dma_list_add);
 895
 896int vme_dma_list_exec(struct vme_dma_list *list)
 897{
 898        struct vme_bridge *bridge = list->parent->parent;
 899        int retval;
 900
 901        if (bridge->dma_list_exec == NULL) {
 902                printk("Link List DMA execution not supported\n");
 903                return -EINVAL;
 904        }
 905
 906        mutex_lock(&(list->mtx));
 907
 908        retval = bridge->dma_list_exec(list);
 909
 910        mutex_unlock(&(list->mtx));
 911
 912        return retval;
 913}
 914EXPORT_SYMBOL(vme_dma_list_exec);
 915
 916int vme_dma_list_free(struct vme_dma_list *list)
 917{
 918        struct vme_bridge *bridge = list->parent->parent;
 919        int retval;
 920
 921        if (bridge->dma_list_empty == NULL) {
 922                printk("Emptying of Link Lists not supported\n");
 923                return -EINVAL;
 924        }
 925
 926        if (mutex_trylock(&(list->mtx))) {
 927                printk("Link List in use\n");
 928                return -EINVAL;
 929        }
 930
 931        /*
 932         * Empty out all of the entries from the dma list. We need to go to the
 933         * low level driver as dma entries are driver specific.
 934         */
 935        retval = bridge->dma_list_empty(list);
 936        if (retval) {
 937                printk("Unable to empty link-list entries\n");
 938                mutex_unlock(&(list->mtx));
 939                return retval;
 940        }
 941        mutex_unlock(&(list->mtx));
 942        kfree(list);
 943
 944        return retval;
 945}
 946EXPORT_SYMBOL(vme_dma_list_free);
 947
 948int vme_dma_free(struct vme_resource *resource)
 949{
 950        struct vme_dma_resource *ctrlr;
 951
 952        if (resource->type != VME_DMA) {
 953                printk("Not a DMA resource\n");
 954                return -EINVAL;
 955        }
 956
 957        ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
 958
 959        if (mutex_trylock(&(ctrlr->mtx))) {
 960                printk("Resource busy, can't free\n");
 961                return -EBUSY;
 962        }
 963
 964        if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) {
 965                printk("Resource still processing transfers\n");
 966                mutex_unlock(&(ctrlr->mtx));
 967                return -EBUSY;
 968        }
 969
 970        ctrlr->locked = 0;
 971
 972        mutex_unlock(&(ctrlr->mtx));
 973
 974        return 0;
 975}
 976EXPORT_SYMBOL(vme_dma_free);
 977
 978int vme_request_irq(struct device *dev, int level, int statid,
 979        void (*callback)(int level, int vector, void *priv_data),
 980        void *priv_data)
 981{
 982        struct vme_bridge *bridge;
 983
 984        bridge = dev_to_bridge(dev);
 985        if (bridge == NULL) {
 986                printk(KERN_ERR "Can't find VME bus\n");
 987                return -EINVAL;
 988        }
 989
 990        if((level < 1) || (level > 7)) {
 991                printk(KERN_WARNING "Invalid interrupt level\n");
 992                return -EINVAL;
 993        }
 994
 995        if (bridge->request_irq == NULL) {
 996                printk("Registering interrupts not supported\n");
 997                return -EINVAL;
 998        }
 999
1000        return bridge->request_irq(level, statid, callback, priv_data);
1001}
1002EXPORT_SYMBOL(vme_request_irq);
1003
1004void vme_free_irq(struct device *dev, int level, int statid)
1005{
1006        struct vme_bridge *bridge;
1007
1008        bridge = dev_to_bridge(dev);
1009        if (bridge == NULL) {
1010                printk(KERN_ERR "Can't find VME bus\n");
1011                return;
1012        }
1013
1014        if((level < 1) || (level > 7)) {
1015                printk(KERN_WARNING "Invalid interrupt level\n");
1016                return;
1017        }
1018
1019        if (bridge->free_irq == NULL) {
1020                printk("Freeing interrupts not supported\n");
1021                return;
1022        }
1023
1024        bridge->free_irq(level, statid);
1025}
1026EXPORT_SYMBOL(vme_free_irq);
1027
1028int vme_generate_irq(struct device *dev, int level, int statid)
1029{
1030        struct vme_bridge *bridge;
1031
1032        bridge = dev_to_bridge(dev);
1033        if (bridge == NULL) {
1034                printk(KERN_ERR "Can't find VME bus\n");
1035                return -EINVAL;
1036        }
1037
1038        if((level < 1) || (level > 7)) {
1039                printk(KERN_WARNING "Invalid interrupt level\n");
1040                return -EINVAL;
1041        }
1042
1043        if (bridge->generate_irq == NULL) {
1044                printk("Interrupt generation not supported\n");
1045                return -EINVAL;
1046        }
1047
1048        return bridge->generate_irq(level, statid);
1049}
1050EXPORT_SYMBOL(vme_generate_irq);
1051
1052/*
1053 * Request the location monitor, return resource or NULL
1054 */
1055struct vme_resource *vme_lm_request(struct device *dev)
1056{
1057        struct vme_bridge *bridge;
1058        struct list_head *lm_pos = NULL;
1059        struct vme_lm_resource *allocated_lm = NULL;
1060        struct vme_lm_resource *lm = NULL;
1061        struct vme_resource *resource = NULL;
1062
1063        bridge = dev_to_bridge(dev);
1064        if (bridge == NULL) {
1065                printk(KERN_ERR "Can't find VME bus\n");
1066                goto err_bus;
1067        }
1068
1069        /* Loop through DMA resources */
1070        list_for_each(lm_pos, &(bridge->lm_resources)) {
1071                lm = list_entry(lm_pos,
1072                        struct vme_lm_resource, list);
1073
1074                if (lm == NULL) {
1075                        printk(KERN_ERR "Registered NULL Location Monitor "
1076                                "resource\n");
1077                        continue;
1078                }
1079
1080                /* Find an unlocked controller */
1081                mutex_lock(&(lm->mtx));
1082                if (lm->locked == 0) {
1083                        lm->locked = 1;
1084                        mutex_unlock(&(lm->mtx));
1085                        allocated_lm = lm;
1086                        break;
1087                }
1088                mutex_unlock(&(lm->mtx));
1089        }
1090
1091        /* Check to see if we found a resource */
1092        if (allocated_lm == NULL)
1093                goto err_lm;
1094
1095        resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
1096        if (resource == NULL) {
1097                printk(KERN_ERR "Unable to allocate resource structure\n");
1098                goto err_alloc;
1099        }
1100        resource->type = VME_LM;
1101        resource->entry = &(allocated_lm->list);
1102
1103        return resource;
1104
1105err_alloc:
1106        /* Unlock image */
1107        mutex_lock(&(lm->mtx));
1108        lm->locked = 0;
1109        mutex_unlock(&(lm->mtx));
1110err_lm:
1111err_bus:
1112        return NULL;
1113}
1114EXPORT_SYMBOL(vme_lm_request);
1115
1116int vme_lm_count(struct vme_resource *resource)
1117{
1118        struct vme_lm_resource *lm;
1119
1120        if (resource->type != VME_LM) {
1121                printk(KERN_ERR "Not a Location Monitor resource\n");
1122                return -EINVAL;
1123        }
1124
1125        lm = list_entry(resource->entry, struct vme_lm_resource, list);
1126
1127        return lm->monitors;
1128}
1129EXPORT_SYMBOL(vme_lm_count);
1130
1131int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base,
1132        vme_address_t aspace, vme_cycle_t cycle)
1133{
1134        struct vme_bridge *bridge = find_bridge(resource);
1135        struct vme_lm_resource *lm;
1136
1137        if (resource->type != VME_LM) {
1138                printk(KERN_ERR "Not a Location Monitor resource\n");
1139                return -EINVAL;
1140        }
1141
1142        lm = list_entry(resource->entry, struct vme_lm_resource, list);
1143
1144        if (bridge->lm_set == NULL) {
1145                printk(KERN_ERR "vme_lm_set not supported\n");
1146                return -EINVAL;
1147        }
1148
1149        /* XXX Check parameters */
1150
1151        return lm->parent->lm_set(lm, lm_base, aspace, cycle);
1152}
1153EXPORT_SYMBOL(vme_lm_set);
1154
1155int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base,
1156        vme_address_t *aspace, vme_cycle_t *cycle)
1157{
1158        struct vme_bridge *bridge = find_bridge(resource);
1159        struct vme_lm_resource *lm;
1160
1161        if (resource->type != VME_LM) {
1162                printk(KERN_ERR "Not a Location Monitor resource\n");
1163                return -EINVAL;
1164        }
1165
1166        lm = list_entry(resource->entry, struct vme_lm_resource, list);
1167
1168        if (bridge->lm_get == NULL) {
1169                printk(KERN_ERR "vme_lm_get not supported\n");
1170                return -EINVAL;
1171        }
1172
1173        return bridge->lm_get(lm, lm_base, aspace, cycle);
1174}
1175EXPORT_SYMBOL(vme_lm_get);
1176
1177int vme_lm_attach(struct vme_resource *resource, int monitor,
1178        void (*callback)(int))
1179{
1180        struct vme_bridge *bridge = find_bridge(resource);
1181        struct vme_lm_resource *lm;
1182
1183        if (resource->type != VME_LM) {
1184                printk(KERN_ERR "Not a Location Monitor resource\n");
1185                return -EINVAL;
1186        }
1187
1188        lm = list_entry(resource->entry, struct vme_lm_resource, list);
1189
1190        if (bridge->lm_attach == NULL) {
1191                printk(KERN_ERR "vme_lm_attach not supported\n");
1192                return -EINVAL;
1193        }
1194
1195        return bridge->lm_attach(lm, monitor, callback);
1196}
1197EXPORT_SYMBOL(vme_lm_attach);
1198
1199int vme_lm_detach(struct vme_resource *resource, int monitor)
1200{
1201        struct vme_bridge *bridge = find_bridge(resource);
1202        struct vme_lm_resource *lm;
1203
1204        if (resource->type != VME_LM) {
1205                printk(KERN_ERR "Not a Location Monitor resource\n");
1206                return -EINVAL;
1207        }
1208
1209        lm = list_entry(resource->entry, struct vme_lm_resource, list);
1210
1211        if (bridge->lm_detach == NULL) {
1212                printk(KERN_ERR "vme_lm_detach not supported\n");
1213                return -EINVAL;
1214        }
1215
1216        return bridge->lm_detach(lm, monitor);
1217}
1218EXPORT_SYMBOL(vme_lm_detach);
1219
1220void vme_lm_free(struct vme_resource *resource)
1221{
1222        struct vme_lm_resource *lm;
1223
1224        if (resource->type != VME_LM) {
1225                printk(KERN_ERR "Not a Location Monitor resource\n");
1226                return;
1227        }
1228
1229        lm = list_entry(resource->entry, struct vme_lm_resource, list);
1230
1231        if (mutex_trylock(&(lm->mtx))) {
1232                printk(KERN_ERR "Resource busy, can't free\n");
1233                return;
1234        }
1235
1236        /* XXX Check to see that there aren't any callbacks still attached */
1237
1238        lm->locked = 0;
1239
1240        mutex_unlock(&(lm->mtx));
1241}
1242EXPORT_SYMBOL(vme_lm_free);
1243
1244int vme_slot_get(struct device *bus)
1245{
1246        struct vme_bridge *bridge;
1247
1248        bridge = dev_to_bridge(bus);
1249        if (bridge == NULL) {
1250                printk(KERN_ERR "Can't find VME bus\n");
1251                return -EINVAL;
1252        }
1253
1254        if (bridge->slot_get == NULL) {
1255                printk("vme_slot_get not supported\n");
1256                return -EINVAL;
1257        }
1258
1259        return bridge->slot_get();
1260}
1261EXPORT_SYMBOL(vme_slot_get);
1262
1263
1264/* - Bridge Registration --------------------------------------------------- */
1265
1266static int vme_alloc_bus_num(void)
1267{
1268        int i;
1269
1270        mutex_lock(&vme_bus_num_mtx);
1271        for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) {
1272                if (((vme_bus_numbers >> i) & 0x1) == 0) {
1273                        vme_bus_numbers |= (0x1 << i);
1274                        break;
1275                }
1276        }
1277        mutex_unlock(&vme_bus_num_mtx);
1278
1279        return i;
1280}
1281
1282static void vme_free_bus_num(int bus)
1283{
1284        mutex_lock(&vme_bus_num_mtx);
1285        vme_bus_numbers |= ~(0x1 << bus);
1286        mutex_unlock(&vme_bus_num_mtx);
1287}
1288
1289int vme_register_bridge (struct vme_bridge *bridge)
1290{
1291        struct device *dev;
1292        int retval;
1293        int i;
1294
1295        bridge->num = vme_alloc_bus_num();
1296
1297        /* This creates 32 vme "slot" devices. This equates to a slot for each
1298         * ID available in a system conforming to the ANSI/VITA 1-1994
1299         * specification.
1300         */
1301        for (i = 0; i < VME_SLOTS_MAX; i++) {
1302                dev = &(bridge->dev[i]);
1303                memset(dev, 0, sizeof(struct device));
1304
1305                dev->parent = bridge->parent;
1306                dev->bus = &(vme_bus_type);
1307                /*
1308                 * We save a pointer to the bridge in platform_data so that we
1309                 * can get to it later. We keep driver_data for use by the
1310                 * driver that binds against the slot
1311                 */
1312                dev->platform_data = bridge;
1313                dev_set_name(dev, "vme-%x.%x", bridge->num, i + 1);
1314
1315                retval = device_register(dev);
1316                if(retval)
1317                        goto err_reg;
1318        }
1319
1320        return retval;
1321
1322        i = VME_SLOTS_MAX;
1323err_reg:
1324        while (i > -1) {
1325                dev = &(bridge->dev[i]);
1326                device_unregister(dev);
1327        }
1328        vme_free_bus_num(bridge->num);
1329        return retval;
1330}
1331EXPORT_SYMBOL(vme_register_bridge);
1332
1333void vme_unregister_bridge (struct vme_bridge *bridge)
1334{
1335        int i;
1336        struct device *dev;
1337
1338
1339        for (i = 0; i < VME_SLOTS_MAX; i++) {
1340                dev = &(bridge->dev[i]);
1341                device_unregister(dev);
1342        }
1343        vme_free_bus_num(bridge->num);
1344}
1345EXPORT_SYMBOL(vme_unregister_bridge);
1346
1347
1348/* - Driver Registration --------------------------------------------------- */
1349
1350int vme_register_driver (struct vme_driver *drv)
1351{
1352        drv->driver.name = drv->name;
1353        drv->driver.bus = &vme_bus_type;
1354
1355        return driver_register(&drv->driver);
1356}
1357EXPORT_SYMBOL(vme_register_driver);
1358
1359void vme_unregister_driver (struct vme_driver *drv)
1360{
1361        driver_unregister(&drv->driver);
1362}
1363EXPORT_SYMBOL(vme_unregister_driver);
1364
1365/* - Bus Registration ------------------------------------------------------ */
1366
1367int vme_calc_slot(struct device *dev)
1368{
1369        struct vme_bridge *bridge;
1370        int num;
1371
1372        bridge = dev_to_bridge(dev);
1373
1374        /* Determine slot number */
1375        num = 0;
1376        while(num < VME_SLOTS_MAX) {
1377                if(&(bridge->dev[num]) == dev) {
1378                        break;
1379                }
1380                num++;
1381        }
1382        if (num == VME_SLOTS_MAX) {
1383                dev_err(dev, "Failed to identify slot\n");
1384                num = 0;
1385                goto err_dev;
1386        }
1387        num++;
1388
1389err_dev:
1390        return num;
1391}
1392
1393static struct vme_driver *dev_to_vme_driver(struct device *dev)
1394{
1395        if(dev->driver == NULL)
1396                printk("Bugger dev->driver is NULL\n");
1397
1398        return container_of(dev->driver, struct vme_driver, driver);
1399}
1400
1401static int vme_bus_match(struct device *dev, struct device_driver *drv)
1402{
1403        struct vme_bridge *bridge;
1404        struct vme_driver *driver;
1405        int i, num;
1406
1407        bridge = dev_to_bridge(dev);
1408        driver = container_of(drv, struct vme_driver, driver);
1409
1410        num = vme_calc_slot(dev);
1411        if (!num)
1412                goto err_dev;
1413
1414        if (driver->bind_table == NULL) {
1415                dev_err(dev, "Bind table NULL\n");
1416                goto err_table;
1417        }
1418
1419        i = 0;
1420        while((driver->bind_table[i].bus != 0) ||
1421                (driver->bind_table[i].slot != 0)) {
1422
1423                if (bridge->num == driver->bind_table[i].bus) {
1424                        if (num == driver->bind_table[i].slot)
1425                                return 1;
1426
1427                        if (driver->bind_table[i].slot == VME_SLOT_ALL)
1428                                return 1;
1429
1430                        if ((driver->bind_table[i].slot == VME_SLOT_CURRENT) &&
1431                                (num == vme_slot_get(dev)))
1432                                return 1;
1433                }
1434                i++;
1435        }
1436
1437err_dev:
1438err_table:
1439        return 0;
1440}
1441
1442static int vme_bus_probe(struct device *dev)
1443{
1444        struct vme_bridge *bridge;
1445        struct vme_driver *driver;
1446        int retval = -ENODEV;
1447
1448        driver = dev_to_vme_driver(dev);
1449        bridge = dev_to_bridge(dev);
1450
1451        if(driver->probe != NULL) {
1452                retval = driver->probe(dev, bridge->num, vme_calc_slot(dev));
1453        }
1454
1455        return retval;
1456}
1457
1458static int vme_bus_remove(struct device *dev)
1459{
1460        struct vme_bridge *bridge;
1461        struct vme_driver *driver;
1462        int retval = -ENODEV;
1463
1464        driver = dev_to_vme_driver(dev);
1465        bridge = dev_to_bridge(dev);
1466
1467        if(driver->remove != NULL) {
1468                retval = driver->remove(dev, bridge->num, vme_calc_slot(dev));
1469        }
1470
1471        return retval;
1472}
1473
1474struct bus_type vme_bus_type = {
1475        .name = "vme",
1476        .match = vme_bus_match,
1477        .probe = vme_bus_probe,
1478        .remove = vme_bus_remove,
1479};
1480EXPORT_SYMBOL(vme_bus_type);
1481
1482static int __init vme_init (void)
1483{
1484        return bus_register(&vme_bus_type);
1485}
1486
1487static void __exit vme_exit (void)
1488{
1489        bus_unregister(&vme_bus_type);
1490}
1491
1492MODULE_DESCRIPTION("VME bridge driver framework");
1493MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
1494MODULE_LICENSE("GPL");
1495
1496module_init(vme_init);
1497module_exit(vme_exit);
1498