linux-old/drivers/ieee1394/raw1394.c
<<
>>
Prefs
   1/*
   2 * IEEE 1394 for Linux
   3 *
   4 * Raw interface to the bus
   5 *
   6 * Copyright (C) 1999, 2000 Andreas E. Bombe
   7 *               2001, 2002 Manfred Weihs <weihs@ict.tuwien.ac.at>
   8 *                     2002 Christian Toegel <christian.toegel@gmx.at>
   9 *
  10 * This code is licensed under the GPL.  See the file COPYING in the root
  11 * directory of the kernel sources for details.
  12 *
  13 *
  14 * Contributions:
  15 *
  16 * Manfred Weihs <weihs@ict.tuwien.ac.at>
  17 *        configuration ROM manipulation
  18 *        address range mapping
  19 *        adaptation for new (transparent) loopback mechanism
  20 *        sending of arbitrary async packets
  21 * Christian Toegel <christian.toegel@gmx.at>
  22 *        address range mapping
  23 *        lock64 request
  24 *        transmit physical packet
  25 *        busreset notification control (switch on/off)
  26 *        busreset with selection of type (short/long)
  27 *        request_reply
  28 */
  29
  30#include <linux/kernel.h>
  31#include <linux/list.h>
  32#include <linux/string.h>
  33#include <linux/slab.h>
  34#include <linux/fs.h>
  35#include <linux/poll.h>
  36#include <linux/module.h>
  37#include <linux/init.h>
  38#include <linux/version.h>
  39#include <linux/smp_lock.h>
  40#include <linux/vmalloc.h>
  41#include <asm/uaccess.h>
  42#include <asm/atomic.h>
  43#include <linux/devfs_fs_kernel.h>
  44
  45#include "ieee1394.h"
  46#include "ieee1394_types.h"
  47#include "ieee1394_core.h"
  48#include "nodemgr.h"
  49#include "hosts.h"
  50#include "highlevel.h"
  51#include "iso.h"
  52#include "ieee1394_transactions.h"
  53#include "raw1394.h"
  54#include "raw1394-private.h"
  55
  56#if BITS_PER_LONG == 64
  57#define int2ptr(x) ((void *)x)
  58#define ptr2int(x) ((u64)x)
  59#else
  60#define int2ptr(x) ((void *)(u32)x)
  61#define ptr2int(x) ((u64)(u32)x)
  62#endif
  63
  64#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
  65#define RAW1394_DEBUG
  66#endif
  67
  68#ifdef RAW1394_DEBUG
  69#define DBGMSG(fmt, args...) \
  70printk(KERN_INFO "raw1394:" fmt "\n" , ## args)
  71#else
  72#define DBGMSG(fmt, args...)
  73#endif
  74
  75static devfs_handle_t devfs_handle;
  76
  77static LIST_HEAD(host_info_list);
  78static int host_count;
  79static spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED;
  80static atomic_t internal_generation = ATOMIC_INIT(0);
  81
  82static atomic_t iso_buffer_size;
  83static const int iso_buffer_max = 4 * 1024 * 1024; /* 4 MB */
  84
  85static struct hpsb_highlevel raw1394_highlevel;
  86
  87static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
  88                     u64 addr, size_t length, u16 flags);
  89static int arm_write (struct hpsb_host *host, int nodeid, int destid,
  90                      quadlet_t *data, u64 addr, size_t length, u16 flags);
  91static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
  92             u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags);
  93static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
  94               u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags);
  95static struct hpsb_address_ops arm_ops = {
  96        .read   = arm_read,
  97        .write  = arm_write,
  98        .lock   = arm_lock,
  99        .lock64 = arm_lock64,
 100};
 101
 102static void queue_complete_cb(struct pending_request *req);
 103
 104static struct pending_request *__alloc_pending_request(int flags)
 105{
 106        struct pending_request *req;
 107
 108        req = (struct pending_request *)kmalloc(sizeof(struct pending_request),
 109                                                flags);
 110        if (req != NULL) {
 111                memset(req, 0, sizeof(struct pending_request));
 112                INIT_LIST_HEAD(&req->list);
 113        }
 114
 115        return req;
 116}
 117
 118static inline struct pending_request *alloc_pending_request(void)
 119{
 120        return __alloc_pending_request(SLAB_KERNEL);
 121}
 122
 123static void free_pending_request(struct pending_request *req)
 124{
 125        if (req->ibs) {
 126                if (atomic_dec_and_test(&req->ibs->refcount)) {
 127                        atomic_sub(req->ibs->data_size, &iso_buffer_size);
 128                        kfree(req->ibs);
 129                }
 130        } else if (req->free_data) {
 131                kfree(req->data);
 132        }
 133        free_hpsb_packet(req->packet);
 134        kfree(req);
 135}
 136
 137/* fi->reqlists_lock must be taken */
 138static void __queue_complete_req(struct pending_request *req)
 139{
 140        struct file_info *fi = req->file_info;
 141        list_del(&req->list);
 142        list_add_tail(&req->list, &fi->req_complete);
 143
 144        up(&fi->complete_sem);
 145        wake_up_interruptible(&fi->poll_wait_complete);
 146}
 147
 148static void queue_complete_req(struct pending_request *req)
 149{
 150        unsigned long flags;
 151        struct file_info *fi = req->file_info;
 152
 153        spin_lock_irqsave(&fi->reqlists_lock, flags);
 154        __queue_complete_req(req);
 155        spin_unlock_irqrestore(&fi->reqlists_lock, flags);
 156}
 157
 158static void queue_complete_cb(struct pending_request *req)
 159{
 160        struct hpsb_packet *packet = req->packet;
 161        int rcode = (packet->header[1] >> 12) & 0xf;
 162
 163        switch (packet->ack_code) {
 164        case ACKX_NONE:
 165        case ACKX_SEND_ERROR:
 166                req->req.error = RAW1394_ERROR_SEND_ERROR;
 167                break;
 168        case ACKX_ABORTED:
 169                req->req.error = RAW1394_ERROR_ABORTED;
 170                break;
 171        case ACKX_TIMEOUT:
 172                req->req.error = RAW1394_ERROR_TIMEOUT;
 173                break;
 174        default:
 175                req->req.error = (packet->ack_code << 16) | rcode;
 176                break;
 177        }
 178
 179        if (!((packet->ack_code == ACK_PENDING) && (rcode == RCODE_COMPLETE))) {
 180                req->req.length = 0;
 181        }
 182
 183        if ((req->req.type == RAW1394_REQ_ASYNC_READ) ||
 184            (req->req.type == RAW1394_REQ_ASYNC_WRITE) ||
 185            (req->req.type == RAW1394_REQ_ASYNC_STREAM) ||
 186            (req->req.type == RAW1394_REQ_LOCK) ||
 187            (req->req.type == RAW1394_REQ_LOCK64))
 188                hpsb_free_tlabel(packet);
 189
 190        queue_complete_req(req);
 191}
 192
 193
 194static void add_host(struct hpsb_host *host)
 195{
 196        struct host_info *hi;
 197        unsigned long flags;
 198
 199        hi = (struct host_info *)kmalloc(sizeof(struct host_info), GFP_KERNEL);
 200
 201        if (hi != NULL) {
 202                INIT_LIST_HEAD(&hi->list);
 203                hi->host = host;
 204                INIT_LIST_HEAD(&hi->file_info_list);
 205
 206                spin_lock_irqsave(&host_info_lock, flags);
 207                list_add_tail(&hi->list, &host_info_list);
 208                host_count++;
 209                spin_unlock_irqrestore(&host_info_lock, flags);
 210        }
 211
 212        atomic_inc(&internal_generation);
 213}
 214
 215
 216static struct host_info *find_host_info(struct hpsb_host *host)
 217{
 218        struct list_head *lh;
 219        struct host_info *hi;
 220
 221        list_for_each(lh, &host_info_list) {
 222                hi = list_entry(lh, struct host_info, list);
 223                if (hi->host == host) {
 224                        return hi;
 225                }
 226        }
 227
 228        return NULL;
 229}
 230
 231static void remove_host(struct hpsb_host *host)
 232{
 233        struct host_info *hi;
 234        unsigned long flags;
 235
 236        spin_lock_irqsave(&host_info_lock, flags);
 237        hi = find_host_info(host);
 238
 239        if (hi != NULL) {
 240                list_del(&hi->list);
 241                host_count--;
 242                /* 
 243                   FIXME: address ranges should be removed 
 244                   and fileinfo states should be initialized
 245                   (including setting generation to 
 246                   internal-generation ...)
 247                */
 248        }
 249        spin_unlock_irqrestore(&host_info_lock, flags);
 250
 251        if (hi == NULL) {
 252                printk(KERN_ERR "raw1394: attempt to remove unknown host "
 253                       "0x%p\n", host);
 254                return;
 255        }
 256
 257        kfree(hi);
 258
 259        atomic_inc(&internal_generation);
 260}
 261
 262static void host_reset(struct hpsb_host *host)
 263{
 264        unsigned long flags;
 265        struct list_head *lh;
 266        struct host_info *hi;
 267        struct file_info *fi;
 268        struct pending_request *req;
 269
 270        spin_lock_irqsave(&host_info_lock, flags);
 271        hi = find_host_info(host);
 272
 273        if (hi != NULL) {
 274                list_for_each(lh, &hi->file_info_list) {
 275                        fi = list_entry(lh, struct file_info, list);
 276                        if (fi->notification == RAW1394_NOTIFY_ON) {
 277                                req = __alloc_pending_request(SLAB_ATOMIC);
 278
 279                                if (req != NULL) {
 280                                        req->file_info = fi;
 281                                        req->req.type = RAW1394_REQ_BUS_RESET;
 282                                        req->req.generation = get_hpsb_generation(host);
 283                                        req->req.misc = (host->node_id << 16)
 284                                                | host->node_count;
 285                                        if (fi->protocol_version > 3) {
 286                                                req->req.misc |= (NODEID_TO_NODE(host->irm_id)
 287                                                                  << 8);
 288                                        }
 289
 290                                        queue_complete_req(req);
 291                                }
 292                        }
 293                }
 294        }
 295        spin_unlock_irqrestore(&host_info_lock, flags);
 296}
 297
 298static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
 299                        size_t length)
 300{
 301        unsigned long flags;
 302        struct list_head *lh;
 303        struct host_info *hi;
 304        struct file_info *fi;
 305        struct pending_request *req;
 306        struct iso_block_store *ibs = NULL;
 307        LIST_HEAD(reqs);
 308
 309        if ((atomic_read(&iso_buffer_size) + length) > iso_buffer_max) {
 310                HPSB_INFO("dropped iso packet");
 311                return;
 312        }
 313
 314        spin_lock_irqsave(&host_info_lock, flags);
 315        hi = find_host_info(host);
 316
 317        if (hi != NULL) {
 318                list_for_each(lh, &hi->file_info_list) {
 319                        fi = list_entry(lh, struct file_info, list);
 320
 321                        if (!(fi->listen_channels & (1ULL << channel))) {
 322                                continue;
 323                        }
 324
 325                        req = __alloc_pending_request(SLAB_ATOMIC);
 326                        if (!req) break;
 327
 328                        if (!ibs) {
 329                                ibs = kmalloc(sizeof(struct iso_block_store)
 330                                              + length, SLAB_ATOMIC);
 331                                if (!ibs) {
 332                                        kfree(req);
 333                                        break;
 334                                }
 335
 336                                atomic_add(length, &iso_buffer_size);
 337                                atomic_set(&ibs->refcount, 0);
 338                                ibs->data_size = length;
 339                                memcpy(ibs->data, data, length);
 340                        }
 341
 342                        atomic_inc(&ibs->refcount);
 343
 344                        req->file_info = fi;
 345                        req->ibs = ibs;
 346                        req->data = ibs->data;
 347                        req->req.type = RAW1394_REQ_ISO_RECEIVE;
 348                        req->req.generation = get_hpsb_generation(host);
 349                        req->req.misc = 0;
 350                        req->req.recvb = ptr2int(fi->iso_buffer);
 351                        req->req.length = min(length, fi->iso_buffer_length);
 352                        
 353                        list_add_tail(&req->list, &reqs);
 354                }
 355        }
 356        spin_unlock_irqrestore(&host_info_lock, flags);
 357
 358        lh = reqs.next;
 359        while (lh != &reqs) {
 360                req = list_entry(lh, struct pending_request, list);
 361                lh = lh->next;
 362
 363                queue_complete_req(req);
 364        }
 365}
 366
 367static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
 368                        int cts, u8 *data, size_t length)
 369{
 370        unsigned long flags;
 371        struct list_head *lh;
 372        struct host_info *hi;
 373        struct file_info *fi;
 374        struct pending_request *req;
 375        struct iso_block_store *ibs = NULL;
 376        LIST_HEAD(reqs);
 377
 378        if ((atomic_read(&iso_buffer_size) + length) > iso_buffer_max) {
 379                HPSB_INFO("dropped fcp request");
 380                return;
 381        }
 382
 383        spin_lock_irqsave(&host_info_lock, flags);
 384        hi = find_host_info(host);
 385
 386        if (hi != NULL) {
 387                list_for_each(lh, &hi->file_info_list) {
 388                        fi = list_entry(lh, struct file_info, list);
 389
 390                        if (!fi->fcp_buffer) {
 391                                continue;
 392                        }
 393
 394                        req = __alloc_pending_request(SLAB_ATOMIC);
 395                        if (!req) break;
 396
 397                        if (!ibs) {
 398                                ibs = kmalloc(sizeof(struct iso_block_store)
 399                                              + length, SLAB_ATOMIC);
 400                                if (!ibs) {
 401                                        kfree(req);
 402                                        break;
 403                                }
 404
 405                                atomic_add(length, &iso_buffer_size);
 406                                atomic_set(&ibs->refcount, 0);
 407                                ibs->data_size = length;
 408                                memcpy(ibs->data, data, length);
 409                        }
 410
 411                        atomic_inc(&ibs->refcount);
 412
 413                        req->file_info = fi;
 414                        req->ibs = ibs;
 415                        req->data = ibs->data;
 416                        req->req.type = RAW1394_REQ_FCP_REQUEST;
 417                        req->req.generation = get_hpsb_generation(host);
 418                        req->req.misc = nodeid | (direction << 16);
 419                        req->req.recvb = ptr2int(fi->fcp_buffer);
 420                        req->req.length = length;
 421                        
 422                        list_add_tail(&req->list, &reqs);
 423                }
 424        }
 425        spin_unlock_irqrestore(&host_info_lock, flags);
 426
 427        lh = reqs.next;
 428        while (lh != &reqs) {
 429                req = list_entry(lh, struct pending_request, list);
 430                lh = lh->next;
 431
 432                queue_complete_req(req);
 433        }
 434}
 435
 436
 437static ssize_t raw1394_read(struct file *file, char *buffer, size_t count,
 438                    loff_t *offset_is_ignored)
 439{
 440        struct file_info *fi = (struct file_info *)file->private_data;
 441        struct list_head *lh;
 442        struct pending_request *req;
 443
 444        if (count != sizeof(struct raw1394_request)) {
 445                return -EINVAL;
 446        }
 447
 448        if (!access_ok(VERIFY_WRITE, buffer, count)) {
 449                return -EFAULT;
 450        }
 451
 452        if (file->f_flags & O_NONBLOCK) {
 453                if (down_trylock(&fi->complete_sem)) {
 454                        return -EAGAIN;
 455                }
 456        } else {
 457                if (down_interruptible(&fi->complete_sem)) {
 458                        return -ERESTARTSYS;
 459                }
 460        }
 461
 462        spin_lock_irq(&fi->reqlists_lock);
 463        lh = fi->req_complete.next;
 464        list_del(lh);
 465        spin_unlock_irq(&fi->reqlists_lock);
 466
 467        req = list_entry(lh, struct pending_request, list);
 468
 469        if (req->req.length) {
 470                if (copy_to_user(int2ptr(req->req.recvb), req->data,
 471                                 req->req.length)) {
 472                        req->req.error = RAW1394_ERROR_MEMFAULT;
 473                }
 474        }
 475        __copy_to_user(buffer, &req->req, sizeof(req->req));
 476
 477        free_pending_request(req);
 478        return sizeof(struct raw1394_request);
 479}
 480
 481
 482static int state_opened(struct file_info *fi, struct pending_request *req)
 483{
 484        if (req->req.type == RAW1394_REQ_INITIALIZE) {
 485                switch (req->req.misc) {
 486                case RAW1394_KERNELAPI_VERSION:
 487                case 3:
 488                        fi->state = initialized;
 489                        fi->protocol_version = req->req.misc;
 490                        req->req.error = RAW1394_ERROR_NONE;
 491                        req->req.generation = atomic_read(&internal_generation);
 492                        break;
 493
 494                default:
 495                        req->req.error = RAW1394_ERROR_COMPAT;
 496                        req->req.misc = RAW1394_KERNELAPI_VERSION;
 497                }
 498        } else {
 499                req->req.error = RAW1394_ERROR_STATE_ORDER;
 500        }
 501
 502        req->req.length = 0;
 503        queue_complete_req(req);
 504        return sizeof(struct raw1394_request);
 505}
 506
 507static int state_initialized(struct file_info *fi, struct pending_request *req)
 508{
 509        struct list_head *lh;
 510        struct host_info *hi;
 511        struct raw1394_khost_list *khl;
 512
 513        if (req->req.generation != atomic_read(&internal_generation)) {
 514                req->req.error = RAW1394_ERROR_GENERATION;
 515                req->req.generation = atomic_read(&internal_generation);
 516                req->req.length = 0;
 517                queue_complete_req(req);
 518                return sizeof(struct raw1394_request);
 519        }
 520
 521        switch (req->req.type) {
 522        case RAW1394_REQ_LIST_CARDS:
 523                spin_lock_irq(&host_info_lock);
 524                khl = kmalloc(sizeof(struct raw1394_khost_list) * host_count,
 525                              SLAB_ATOMIC);
 526
 527                if (khl != NULL) {
 528                        req->req.misc = host_count;
 529                        req->data = (quadlet_t *)khl;
 530                        
 531                        list_for_each(lh, &host_info_list) {
 532                                hi = list_entry(lh, struct host_info, list);
 533
 534                                khl->nodes = hi->host->node_count;
 535                                strcpy(khl->name, hi->host->driver->name);
 536
 537                                khl++;
 538                        }
 539                }
 540                spin_unlock_irq(&host_info_lock);
 541
 542                if (khl != NULL) {
 543                        req->req.error = RAW1394_ERROR_NONE;
 544                        req->req.length = min(req->req.length,
 545                                              (u32)(sizeof(struct raw1394_khost_list)
 546                                              * req->req.misc));
 547                        req->free_data = 1;
 548                } else {
 549                        return -ENOMEM;
 550                }
 551                break;
 552
 553        case RAW1394_REQ_SET_CARD:
 554                lh = NULL;
 555
 556                spin_lock_irq(&host_info_lock);
 557                if (req->req.misc < host_count) {
 558                        lh = host_info_list.next;
 559                        while (req->req.misc--) {
 560                                lh = lh->next;
 561                        }
 562                        hi = list_entry(lh, struct host_info, list);
 563                        hpsb_ref_host(hi->host); // XXX Need to handle failure case
 564                        list_add_tail(&fi->list, &hi->file_info_list);
 565                        fi->host = hi->host;
 566                        fi->state = connected;
 567                }
 568                spin_unlock_irq(&host_info_lock);
 569
 570                if (lh != NULL) {
 571                        req->req.error = RAW1394_ERROR_NONE;
 572                        req->req.generation = get_hpsb_generation(fi->host);
 573                        req->req.misc = (fi->host->node_id << 16) 
 574                                | fi->host->node_count;
 575                        if (fi->protocol_version > 3) {
 576                                req->req.misc |= NODEID_TO_NODE(fi->host->irm_id) << 8;
 577                        }
 578                } else {
 579                        req->req.error = RAW1394_ERROR_INVALID_ARG;
 580                }
 581
 582                req->req.length = 0;
 583                break;
 584
 585        default:
 586                req->req.error = RAW1394_ERROR_STATE_ORDER;
 587                req->req.length = 0;
 588                break;
 589        }
 590
 591        queue_complete_req(req);
 592        return sizeof(struct raw1394_request);
 593}
 594
 595static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
 596{
 597        int channel = req->req.misc;
 598
 599        spin_lock_irq(&host_info_lock);
 600        if ((channel > 63) || (channel < -64)) {
 601                req->req.error = RAW1394_ERROR_INVALID_ARG;
 602        } else if (channel >= 0) {
 603                /* allocate channel req.misc */
 604                if (fi->listen_channels & (1ULL << channel)) {
 605                        req->req.error = RAW1394_ERROR_ALREADY;
 606                } else {
 607                        if (hpsb_listen_channel(&raw1394_highlevel, fi->host, channel)) {
 608                                req->req.error = RAW1394_ERROR_ALREADY;
 609                        } else {
 610                                fi->listen_channels |= 1ULL << channel;
 611                                fi->iso_buffer = int2ptr(req->req.recvb);
 612                                fi->iso_buffer_length = req->req.length;
 613                        }
 614                }
 615        } else {
 616                /* deallocate channel (one's complement neg) req.misc */
 617                channel = ~channel;
 618
 619                if (fi->listen_channels & (1ULL << channel)) {
 620                        hpsb_unlisten_channel(&raw1394_highlevel, fi->host, channel);
 621                        fi->listen_channels &= ~(1ULL << channel);
 622                } else {
 623                        req->req.error = RAW1394_ERROR_INVALID_ARG;
 624                }
 625        }
 626
 627        req->req.length = 0;
 628        queue_complete_req(req);
 629        spin_unlock_irq(&host_info_lock);
 630}
 631
 632static void handle_fcp_listen(struct file_info *fi, struct pending_request *req)
 633{
 634        if (req->req.misc) {
 635                if (fi->fcp_buffer) {
 636                        req->req.error = RAW1394_ERROR_ALREADY;
 637                } else {
 638                        fi->fcp_buffer = (u8 *)int2ptr(req->req.recvb);
 639                }
 640        } else {
 641                if (!fi->fcp_buffer) {
 642                        req->req.error = RAW1394_ERROR_ALREADY;
 643                } else {
 644                        fi->fcp_buffer = NULL;
 645                }
 646        }
 647
 648        req->req.length = 0;
 649        queue_complete_req(req);
 650}
 651
 652
 653static int handle_async_request(struct file_info *fi,
 654                                struct pending_request *req, int node)
 655{
 656        struct hpsb_packet *packet = NULL;
 657        u64 addr = req->req.address & 0xffffffffffffULL;
 658
 659        switch (req->req.type) {
 660        case RAW1394_REQ_ASYNC_READ:
 661                DBGMSG("read_request called");
 662                packet = hpsb_make_readpacket(fi->host, node, addr, req->req.length);
 663
 664                if (!packet)
 665                        return -ENOMEM;
 666
 667                if (req->req.length == 4)
 668                        req->data = &packet->header[3];
 669                else
 670                        req->data = packet->data;
 671  
 672                break;
 673
 674        case RAW1394_REQ_ASYNC_WRITE:
 675                DBGMSG("write_request called");
 676
 677                packet = hpsb_make_writepacket(fi->host, node, addr, NULL,
 678                                               req->req.length);
 679                if (!packet)
 680                        return -ENOMEM;
 681
 682                if (req->req.length == 4) {
 683                        if (copy_from_user(&packet->header[3], int2ptr(req->req.sendb),
 684                                        req->req.length))
 685                                req->req.error = RAW1394_ERROR_MEMFAULT;
 686                } else {
 687                        if (copy_from_user(packet->data, int2ptr(req->req.sendb),
 688                                        req->req.length))
 689                                req->req.error = RAW1394_ERROR_MEMFAULT;
 690                }
 691                        
 692                req->req.length = 0;
 693            break;
 694
 695        case RAW1394_REQ_ASYNC_STREAM:
 696                DBGMSG("stream_request called");
 697
 698                packet = hpsb_make_streampacket(fi->host, NULL, req->req.length, node & 0x3f/*channel*/,
 699                                        (req->req.misc >> 16) & 0x3, req->req.misc & 0xf);
 700                if (!packet)
 701                        return -ENOMEM;
 702
 703                if (copy_from_user(packet->data, int2ptr(req->req.sendb),
 704                                   req->req.length))
 705                        req->req.error = RAW1394_ERROR_MEMFAULT;
 706                        
 707                req->req.length = 0;
 708                break;
 709
 710        case RAW1394_REQ_LOCK:
 711                DBGMSG("lock_request called");
 712                if ((req->req.misc == EXTCODE_FETCH_ADD)
 713                    || (req->req.misc == EXTCODE_LITTLE_ADD)) {
 714                        if (req->req.length != 4) {
 715                                req->req.error = RAW1394_ERROR_INVALID_ARG;
 716                                break;
 717                        }
 718                } else {
 719                        if (req->req.length != 8) {
 720                                req->req.error = RAW1394_ERROR_INVALID_ARG;
 721                                break;
 722                        }
 723                }
 724
 725                packet = hpsb_make_lockpacket(fi->host, node, addr,
 726                                              req->req.misc, NULL, 0);
 727                if (!packet) return -ENOMEM;
 728
 729                if (copy_from_user(packet->data, int2ptr(req->req.sendb),
 730                                   req->req.length)) {
 731                        req->req.error = RAW1394_ERROR_MEMFAULT;
 732                        break;
 733                }
 734
 735                req->data = packet->data;
 736                req->req.length = 4;
 737                break;
 738
 739        case RAW1394_REQ_LOCK64:
 740                DBGMSG("lock64_request called");
 741                if ((req->req.misc == EXTCODE_FETCH_ADD)
 742                    || (req->req.misc == EXTCODE_LITTLE_ADD)) {
 743                        if (req->req.length != 8) {
 744                                req->req.error = RAW1394_ERROR_INVALID_ARG;
 745                                break;
 746                        }
 747                } else {
 748                        if (req->req.length != 16) {
 749                                req->req.error = RAW1394_ERROR_INVALID_ARG;
 750                                break;
 751                        }
 752                }
 753                packet = hpsb_make_lock64packet(fi->host, node, addr,
 754                                                req->req.misc, NULL, 0);
 755                if (!packet) return -ENOMEM;
 756
 757                if (copy_from_user(packet->data, int2ptr(req->req.sendb),
 758                                   req->req.length)) {
 759                        req->req.error = RAW1394_ERROR_MEMFAULT;
 760                        break;
 761                }
 762
 763                req->data = packet->data;
 764                req->req.length = 8;
 765                break;
 766
 767        default:
 768                req->req.error = RAW1394_ERROR_STATE_ORDER;
 769        }
 770
 771        req->packet = packet;
 772
 773        if (req->req.error) {
 774                req->req.length = 0;
 775                queue_complete_req(req);
 776                return sizeof(struct raw1394_request);
 777        }
 778
 779        hpsb_set_packet_complete_task(packet, (void(*)(void*))queue_complete_cb, req);
 780
 781        spin_lock_irq(&fi->reqlists_lock);
 782        list_add_tail(&req->list, &fi->req_pending);
 783        spin_unlock_irq(&fi->reqlists_lock);
 784
 785        packet->generation = req->req.generation;
 786
 787        if (!hpsb_send_packet(packet)) {
 788                req->req.error = RAW1394_ERROR_SEND_ERROR;
 789                req->req.length = 0;
 790                hpsb_free_tlabel(packet);
 791                queue_complete_req(req);
 792        }
 793        return sizeof(struct raw1394_request);
 794}
 795
 796static int handle_iso_send(struct file_info *fi, struct pending_request *req,
 797                           int channel)
 798{
 799        struct hpsb_packet *packet;
 800
 801        packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f,
 802                                     (req->req.misc >> 16) & 0x3, req->req.misc & 0xf);
 803        if (!packet)
 804                return -ENOMEM;
 805
 806        packet->speed_code = req->req.address & 0x3;
 807
 808        req->packet = packet;
 809
 810        if (copy_from_user(packet->data, int2ptr(req->req.sendb),
 811                           req->req.length)) {
 812                req->req.error = RAW1394_ERROR_MEMFAULT;
 813                req->req.length = 0;
 814                queue_complete_req(req);
 815                return sizeof(struct raw1394_request);
 816        }
 817
 818        req->req.length = 0;
 819        hpsb_set_packet_complete_task(packet, (void (*)(void*))queue_complete_req, req);
 820
 821        spin_lock_irq(&fi->reqlists_lock);
 822        list_add_tail(&req->list, &fi->req_pending);
 823        spin_unlock_irq(&fi->reqlists_lock);
 824
 825        /* Update the generation of the packet just before sending. */
 826        packet->generation = req->req.generation;
 827
 828        if (!hpsb_send_packet(packet)) {
 829                req->req.error = RAW1394_ERROR_SEND_ERROR;
 830                queue_complete_req(req);
 831        }
 832
 833        return sizeof(struct raw1394_request);
 834}
 835
 836static int handle_async_send(struct file_info *fi, struct pending_request *req)
 837{
 838        struct hpsb_packet *packet;
 839        int header_length = req->req.misc & 0xffff;
 840        int expect_response = req->req.misc >> 16;
 841
 842        if ((header_length > req->req.length) ||
 843            (header_length  < 12))
 844        {
 845                req->req.error = RAW1394_ERROR_INVALID_ARG;
 846                req->req.length = 0;
 847                queue_complete_req(req);
 848                return sizeof(struct raw1394_request);
 849        } 
 850
 851        packet = alloc_hpsb_packet(req->req.length-header_length);
 852        req->packet = packet;
 853        if (!packet) return -ENOMEM;
 854
 855        if (copy_from_user(packet->header, int2ptr(req->req.sendb),
 856                           header_length)) {
 857                req->req.error = RAW1394_ERROR_MEMFAULT;
 858                req->req.length = 0;
 859                queue_complete_req(req);
 860                return sizeof(struct raw1394_request);
 861        }
 862
 863        if (copy_from_user(packet->data, ((u8*) int2ptr(req->req.sendb)) + header_length,
 864                           packet->data_size)) {
 865                req->req.error = RAW1394_ERROR_MEMFAULT;
 866                req->req.length = 0;
 867                queue_complete_req(req);
 868                return sizeof(struct raw1394_request);
 869        }
 870
 871        packet->type = hpsb_async;
 872        packet->node_id = packet->header[0] >> 16;
 873        packet->tcode = (packet->header[0] >> 4) & 0xf;
 874        packet->tlabel = (packet->header[0] >> 10) &0x3f;
 875        packet->host = fi->host;
 876        packet->expect_response = expect_response;
 877        packet->header_size=header_length;
 878        packet->data_size=req->req.length-header_length;
 879
 880        req->req.length = 0;
 881        hpsb_set_packet_complete_task(packet, (void(*)(void*))queue_complete_cb, req);
 882
 883        spin_lock_irq(&fi->reqlists_lock);
 884        list_add_tail(&req->list, &fi->req_pending);
 885        spin_unlock_irq(&fi->reqlists_lock);
 886
 887        /* Update the generation of the packet just before sending. */
 888        packet->generation = req->req.generation;
 889
 890        if (!hpsb_send_packet(packet)) {
 891                req->req.error = RAW1394_ERROR_SEND_ERROR;
 892                queue_complete_req(req);
 893        }
 894
 895        return sizeof(struct raw1394_request);
 896}
 897
 898static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
 899                     u64 addr, size_t length, u16 flags)
 900{
 901        struct pending_request *req;
 902        struct list_head *lh;
 903        struct host_info *hi;
 904        struct file_info *fi = NULL;
 905        struct list_head *entry;
 906        struct arm_addr  *arm_addr = NULL;
 907        struct arm_request  *arm_req = NULL;
 908        struct arm_response *arm_resp = NULL;
 909        int found=0, size=0, rcode=-1;
 910        struct arm_request_response *arm_req_resp = NULL;
 911
 912        DBGMSG("arm_read  called by node: %X"
 913              "addr: %4.4x %8.8x length: %Zu", nodeid,
 914              (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
 915              length);
 916        spin_lock(&host_info_lock);
 917        hi = find_host_info(host); /* search address-entry */
 918        if (hi != NULL) {
 919                list_for_each(lh, &hi->file_info_list) {
 920                        fi = list_entry(lh, struct file_info, list);
 921                        entry = fi->addr_list.next;
 922                        while (entry != &(fi->addr_list)) {
 923                                arm_addr = list_entry(entry, struct arm_addr, addr_list);
 924                                if (((arm_addr->start) <= (addr)) && 
 925                                        ((arm_addr->end) >= (addr+length))) {
 926                                        found = 1;
 927                                        break;
 928                                }
 929                                entry = entry->next;
 930                        }
 931                        if (found) {
 932                                break;
 933                        }
 934                }
 935        }
 936        rcode = -1;
 937        if (!found) {
 938                printk(KERN_ERR "raw1394: arm_read FAILED addr_entry not found"
 939                " -> rcode_address_error\n");
 940                spin_unlock(&host_info_lock);
 941                return (RCODE_ADDRESS_ERROR);
 942        } else {
 943                DBGMSG("arm_read addr_entry FOUND");
 944        }
 945        if (arm_addr->rec_length < length) {
 946                DBGMSG("arm_read blocklength too big -> rcode_data_error");
 947                rcode = RCODE_DATA_ERROR; /* hardware error, data is unavailable */
 948        }
 949        if (rcode == -1) {
 950                if (arm_addr->access_rights & ARM_READ) {
 951                        if (!(arm_addr->client_transactions & ARM_READ)) {
 952                                memcpy(buffer,(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), 
 953                                       length);
 954                                DBGMSG("arm_read -> (rcode_complete)");
 955                                rcode = RCODE_COMPLETE;
 956                        }
 957                } else {
 958                        rcode = RCODE_TYPE_ERROR; /* function not allowed */
 959                        DBGMSG("arm_read -> rcode_type_error (access denied)");
 960                }
 961        }
 962        if (arm_addr->notification_options & ARM_READ) {
 963                DBGMSG("arm_read -> entering notification-section");
 964                req = __alloc_pending_request(SLAB_ATOMIC);
 965                if (!req) {
 966                        DBGMSG("arm_read -> rcode_conflict_error");
 967                        spin_unlock(&host_info_lock);
 968                        return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 
 969                                                        The request may be retried */
 970                }
 971                if (rcode == RCODE_COMPLETE) {
 972                        size =  sizeof(struct arm_request)+sizeof(struct arm_response) +
 973                                length * sizeof(byte_t) +
 974                                sizeof (struct arm_request_response);
 975                } else {
 976                        size =  sizeof(struct arm_request)+sizeof(struct arm_response) +
 977                                sizeof (struct arm_request_response);
 978                }
 979                req->data = kmalloc(size, SLAB_ATOMIC);
 980                if (!(req->data)) {
 981                        free_pending_request(req);
 982                        DBGMSG("arm_read -> rcode_conflict_error");
 983                        spin_unlock(&host_info_lock);
 984                        return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 
 985                                                        The request may be retried */
 986                }
 987                req->free_data=1;
 988                req->file_info = fi;
 989                req->req.type = RAW1394_REQ_ARM;
 990                req->req.generation = get_hpsb_generation(host);
 991                req->req.misc = ( ((length << 16) & (0xFFFF0000)) | (ARM_READ & 0xFF));
 992                req->req.tag  = arm_addr->arm_tag;
 993                req->req.recvb = arm_addr->recvb;
 994                req->req.length = size;
 995                arm_req_resp = (struct arm_request_response *) (req->data);
 996                arm_req  = (struct arm_request *) ((byte_t *)(req->data) + 
 997                        (sizeof (struct arm_request_response)));
 998                arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + 
 999                        (sizeof(struct arm_request)));
1000                arm_req->buffer  = NULL;
1001                arm_resp->buffer = NULL;
1002                if (rcode == RCODE_COMPLETE) {
1003                        arm_resp->buffer = ((byte_t *)(arm_resp) + 
1004                                (sizeof(struct arm_response)));
1005                        memcpy (arm_resp->buffer,
1006                                (arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), 
1007                                length);
1008                        arm_resp->buffer = int2ptr((arm_addr->recvb) + 
1009                                sizeof (struct arm_request_response) +
1010                                sizeof (struct arm_request) +
1011                                sizeof (struct arm_response));
1012                }
1013                arm_resp->buffer_length = (rcode == RCODE_COMPLETE) ? length : 0;
1014                arm_resp->response_code = rcode;
1015                arm_req->buffer_length = 0;
1016                arm_req->generation = req->req.generation;
1017                arm_req->extended_transaction_code = 0;
1018                arm_req->destination_offset = addr;
1019                arm_req->source_nodeid = nodeid;
1020                arm_req->destination_nodeid = host->node_id;
1021                arm_req->tlabel = (flags >> 10) & 0x3f;
1022                arm_req->tcode = (flags >> 4) & 0x0f;
1023                arm_req_resp->request  = int2ptr((arm_addr->recvb) + 
1024                        sizeof (struct arm_request_response));
1025                arm_req_resp->response = int2ptr((arm_addr->recvb) + 
1026                        sizeof (struct arm_request_response) +
1027                        sizeof (struct arm_request));
1028                queue_complete_req(req);
1029        }
1030        spin_unlock(&host_info_lock);
1031        return(rcode);
1032}
1033
1034static int arm_write (struct hpsb_host *host, int nodeid, int destid,
1035                      quadlet_t *data, u64 addr, size_t length, u16 flags)
1036{
1037        struct pending_request *req;
1038        struct list_head *lh;
1039        struct host_info *hi;
1040        struct file_info *fi = NULL;
1041        struct list_head *entry;
1042        struct arm_addr  *arm_addr = NULL;
1043        struct arm_request  *arm_req = NULL;
1044        struct arm_response *arm_resp = NULL;        
1045        int found=0, size=0, rcode=-1, length_conflict=0;
1046        struct arm_request_response *arm_req_resp = NULL;
1047
1048        DBGMSG("arm_write called by node: %X"
1049              "addr: %4.4x %8.8x length: %Zu", nodeid,
1050              (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
1051              length);
1052        spin_lock(&host_info_lock);
1053        hi = find_host_info(host); /* search address-entry */
1054        if (hi != NULL) {
1055                list_for_each(lh, &hi->file_info_list) {
1056                        fi = list_entry(lh, struct file_info, list);
1057                        entry = fi->addr_list.next;
1058                        while (entry != &(fi->addr_list)) {
1059                                arm_addr = list_entry(entry, struct arm_addr, addr_list);
1060                                if (((arm_addr->start) <= (addr)) && 
1061                                        ((arm_addr->end) >= (addr+length))) {
1062                                        found = 1;
1063                                        break;
1064                                }
1065                                entry = entry->next;
1066                        }
1067                        if (found) {
1068                                break;
1069                        }
1070                }
1071        }
1072        rcode = -1;
1073        if (!found) {
1074                printk(KERN_ERR "raw1394: arm_write FAILED addr_entry not found"
1075                " -> rcode_address_error\n");
1076                spin_unlock(&host_info_lock);
1077                return (RCODE_ADDRESS_ERROR);
1078        } else {
1079                DBGMSG("arm_write addr_entry FOUND");
1080        }
1081        if (arm_addr->rec_length < length) {
1082                DBGMSG("arm_write blocklength too big -> rcode_data_error");
1083                length_conflict = 1;
1084                rcode = RCODE_DATA_ERROR; /* hardware error, data is unavailable */
1085        }
1086        if (rcode == -1) {
1087                if (arm_addr->access_rights & ARM_WRITE) {
1088                        if (!(arm_addr->client_transactions & ARM_WRITE)) {
1089                                memcpy((arm_addr->addr_space_buffer)+(addr-(arm_addr->start)),
1090                                        data, length);
1091                                DBGMSG("arm_write -> (rcode_complete)");
1092                                rcode = RCODE_COMPLETE;
1093                        }
1094                } else {
1095                        rcode = RCODE_TYPE_ERROR; /* function not allowed */
1096                        DBGMSG("arm_write -> rcode_type_error (access denied)");
1097                }
1098        }
1099        if (arm_addr->notification_options & ARM_WRITE) {
1100                DBGMSG("arm_write -> entering notification-section");
1101                req = __alloc_pending_request(SLAB_ATOMIC);
1102                if (!req) {
1103                        DBGMSG("arm_write -> rcode_conflict_error");
1104                        spin_unlock(&host_info_lock);
1105                        return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 
1106                                                        The request my be retried */
1107                }
1108                size =  sizeof(struct arm_request)+sizeof(struct arm_response) +
1109                        (length) * sizeof(byte_t) +
1110                        sizeof (struct arm_request_response);
1111                req->data = kmalloc(size, SLAB_ATOMIC);
1112                if (!(req->data)) {
1113                        free_pending_request(req);
1114                        DBGMSG("arm_write -> rcode_conflict_error");
1115                        spin_unlock(&host_info_lock);
1116                        return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 
1117                                                        The request may be retried */
1118                }
1119                req->free_data=1;
1120                req->file_info = fi;
1121                req->req.type = RAW1394_REQ_ARM;
1122                req->req.generation = get_hpsb_generation(host);
1123                req->req.misc = ( ((length << 16) & (0xFFFF0000)) | (ARM_WRITE & 0xFF));
1124                req->req.tag  = arm_addr->arm_tag;
1125                req->req.recvb = arm_addr->recvb;
1126                req->req.length = size;
1127                arm_req_resp = (struct arm_request_response *) (req->data);
1128                arm_req  = (struct arm_request *) ((byte_t *)(req->data) + 
1129                        (sizeof (struct arm_request_response)));
1130                arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + 
1131                        (sizeof(struct arm_request)));
1132                arm_req->buffer = ((byte_t *)(arm_resp) + 
1133                        (sizeof(struct arm_response)));
1134                arm_resp->buffer = NULL;
1135                memcpy (arm_req->buffer, data, length);
1136                arm_req->buffer = int2ptr((arm_addr->recvb) + 
1137                        sizeof (struct arm_request_response) +
1138                        sizeof (struct arm_request) +
1139                        sizeof (struct arm_response));
1140                arm_req->buffer_length = length;
1141                arm_req->generation = req->req.generation;
1142                arm_req->extended_transaction_code = 0;
1143                arm_req->destination_offset = addr;
1144                arm_req->source_nodeid = nodeid;
1145                arm_req->destination_nodeid = destid;
1146                arm_req->tlabel = (flags >> 10) & 0x3f;
1147                arm_req->tcode = (flags >> 4) & 0x0f;
1148                arm_resp->buffer_length = 0;
1149                arm_resp->response_code = rcode;
1150                arm_req_resp->request  = int2ptr((arm_addr->recvb) + 
1151                        sizeof (struct arm_request_response));
1152                arm_req_resp->response = int2ptr((arm_addr->recvb) + 
1153                        sizeof (struct arm_request_response) +
1154                        sizeof (struct arm_request));
1155                queue_complete_req(req);
1156        }
1157        spin_unlock(&host_info_lock);
1158        return(rcode);
1159}
1160
1161static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
1162             u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags)
1163{
1164        struct pending_request *req;
1165        struct list_head *lh;
1166        struct host_info *hi;
1167        struct file_info *fi = NULL;
1168        struct list_head *entry;
1169        struct arm_addr  *arm_addr = NULL;
1170        struct arm_request  *arm_req = NULL;
1171        struct arm_response *arm_resp = NULL;        
1172        int found=0, size=0, rcode=-1;
1173        quadlet_t old, new;
1174        struct arm_request_response *arm_req_resp = NULL;
1175
1176        if (((ext_tcode & 0xFF) == EXTCODE_FETCH_ADD) ||
1177                ((ext_tcode & 0xFF) == EXTCODE_LITTLE_ADD)) {
1178                DBGMSG("arm_lock  called by node: %X "
1179                      "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X", 
1180                      nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
1181                      ext_tcode & 0xFF , be32_to_cpu(data));
1182        } else {
1183                DBGMSG("arm_lock  called by node: %X "
1184                      "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X arg: %8.8X", 
1185                      nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
1186                      ext_tcode & 0xFF , be32_to_cpu(data), be32_to_cpu(arg));
1187        }
1188        spin_lock(&host_info_lock);
1189        hi = find_host_info(host); /* search address-entry */
1190        if (hi != NULL) {
1191                list_for_each(lh, &hi->file_info_list) {
1192                        fi = list_entry(lh, struct file_info, list);
1193                        entry = fi->addr_list.next;
1194                        while (entry != &(fi->addr_list)) {
1195                                arm_addr = list_entry(entry, struct arm_addr, addr_list);
1196                                if (((arm_addr->start) <= (addr)) && 
1197                                        ((arm_addr->end) >= (addr+sizeof(*store)))) {
1198                                        found = 1;
1199                                        break;
1200                                }
1201                                entry = entry->next;
1202                        }
1203                        if (found) {
1204                                break;
1205                        }
1206                }
1207        }
1208        rcode = -1;
1209        if (!found) {
1210                printk(KERN_ERR "raw1394: arm_lock FAILED addr_entry not found"
1211                " -> rcode_address_error\n");
1212                spin_unlock(&host_info_lock);
1213                return (RCODE_ADDRESS_ERROR);
1214        } else {
1215                DBGMSG("arm_lock addr_entry FOUND");
1216        }
1217        if (rcode == -1) {
1218                if (arm_addr->access_rights & ARM_LOCK) {
1219                        if (!(arm_addr->client_transactions & ARM_LOCK)) {
1220                                memcpy(&old,(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)),
1221                                        sizeof(old));
1222                                switch (ext_tcode) {
1223                                        case (EXTCODE_MASK_SWAP):
1224                                                new = data | (old & ~arg);
1225                                                break;
1226                                        case (EXTCODE_COMPARE_SWAP):
1227                                                if (old == arg) {
1228                                                        new = data;
1229                                                } else {
1230                                                        new = old;
1231                                                }
1232                                                break;
1233                                        case (EXTCODE_FETCH_ADD):
1234                                                new = cpu_to_be32(be32_to_cpu(data) + be32_to_cpu(old));
1235                                                break;
1236                                        case (EXTCODE_LITTLE_ADD):
1237                                                new = cpu_to_le32(le32_to_cpu(data) + le32_to_cpu(old));
1238                                                break;
1239                                        case (EXTCODE_BOUNDED_ADD):
1240                                                if (old != arg) {
1241                                                        new = cpu_to_be32(be32_to_cpu(data) + 
1242                                                                be32_to_cpu(old));
1243                                                } else {
1244                                                        new = old;
1245                                                }
1246                                                break;
1247                                        case (EXTCODE_WRAP_ADD):
1248                                                if (old != arg) {
1249                                                        new = cpu_to_be32(be32_to_cpu(data) + 
1250                                                                be32_to_cpu(old));
1251                                                } else {
1252                                                        new = data;
1253                                                }
1254                                                break;
1255                                        default:
1256                                                rcode = RCODE_TYPE_ERROR; /* function not allowed */
1257                                                printk(KERN_ERR "raw1394: arm_lock FAILED "
1258                                                "ext_tcode not allowed -> rcode_type_error\n");
1259                                                break;
1260                                } /*switch*/
1261                                if (rcode == -1) {
1262                                        DBGMSG("arm_lock -> (rcode_complete)");
1263                                        rcode = RCODE_COMPLETE;
1264                                        memcpy (store, &old, sizeof(*store));
1265                                        memcpy ((arm_addr->addr_space_buffer)+
1266                                                (addr-(arm_addr->start)), 
1267                                                &new, sizeof(*store));
1268                                }
1269                        }
1270                } else {
1271                        rcode = RCODE_TYPE_ERROR; /* function not allowed */
1272                        DBGMSG("arm_lock -> rcode_type_error (access denied)");
1273                }
1274        }
1275        if (arm_addr->notification_options & ARM_LOCK) {
1276                DBGMSG("arm_lock -> entering notification-section");
1277                req = __alloc_pending_request(SLAB_ATOMIC);
1278                if (!req) {
1279                        DBGMSG("arm_lock -> rcode_conflict_error");
1280                        spin_unlock(&host_info_lock);
1281                        return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 
1282                                                        The request may be retried */
1283                }
1284                size =  sizeof(struct arm_request)+sizeof(struct arm_response) +
1285                        3 * sizeof(*store) + 
1286                        sizeof (struct arm_request_response);  /* maximum */
1287                req->data = kmalloc(size, SLAB_ATOMIC);
1288                if (!(req->data)) {
1289                        free_pending_request(req);
1290                        DBGMSG("arm_lock -> rcode_conflict_error");
1291                        spin_unlock(&host_info_lock);
1292                        return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 
1293                                                        The request may be retried */
1294                }
1295                req->free_data=1;
1296                arm_req_resp = (struct arm_request_response *) (req->data);
1297                arm_req  = (struct arm_request *) ((byte_t *)(req->data) + 
1298                        (sizeof (struct arm_request_response)));
1299                arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + 
1300                        (sizeof(struct arm_request)));
1301                arm_req->buffer = ((byte_t *)(arm_resp) + 
1302                        (sizeof(struct arm_response)));
1303                arm_resp->buffer = ((byte_t *)(arm_req->buffer) + 
1304                        (2* sizeof(*store)));
1305                if ((ext_tcode == EXTCODE_FETCH_ADD) || 
1306                        (ext_tcode == EXTCODE_LITTLE_ADD)) {
1307                        arm_req->buffer_length = sizeof(*store);
1308                        memcpy (arm_req->buffer, &data, sizeof(*store));
1309
1310                } else {
1311                        arm_req->buffer_length = 2 * sizeof(*store);
1312                        memcpy (arm_req->buffer, &arg,  sizeof(*store));
1313                        memcpy (((arm_req->buffer) + sizeof(*store)), 
1314                                &data, sizeof(*store));
1315                }
1316                if (rcode == RCODE_COMPLETE) {
1317                        arm_resp->buffer_length = sizeof(*store);
1318                        memcpy (arm_resp->buffer, &old, sizeof(*store));
1319                } else {
1320                        arm_resp->buffer = NULL;
1321                        arm_resp->buffer_length = 0;
1322                }
1323                req->file_info = fi;
1324                req->req.type = RAW1394_REQ_ARM;
1325                req->req.generation = get_hpsb_generation(host);
1326                req->req.misc = ( (((sizeof(*store)) << 16) & (0xFFFF0000)) | 
1327                        (ARM_LOCK & 0xFF));
1328                req->req.tag  = arm_addr->arm_tag;
1329                req->req.recvb = arm_addr->recvb;
1330                req->req.length = size;
1331                arm_req->generation = req->req.generation;
1332                arm_req->extended_transaction_code = ext_tcode;
1333                arm_req->destination_offset = addr;
1334                arm_req->source_nodeid = nodeid;
1335                arm_req->destination_nodeid = host->node_id;
1336                arm_req->tlabel = (flags >> 10) & 0x3f;
1337                arm_req->tcode = (flags >> 4) & 0x0f;
1338                arm_resp->response_code = rcode;
1339                arm_req_resp->request  = int2ptr((arm_addr->recvb) + 
1340                        sizeof (struct arm_request_response));
1341                arm_req_resp->response = int2ptr((arm_addr->recvb) + 
1342                        sizeof (struct arm_request_response) +
1343                        sizeof (struct arm_request));
1344                arm_req->buffer = int2ptr((arm_addr->recvb) + 
1345                        sizeof (struct arm_request_response) +
1346                        sizeof (struct arm_request) +
1347                        sizeof (struct arm_response));
1348                arm_resp->buffer = int2ptr((arm_addr->recvb) + 
1349                        sizeof (struct arm_request_response) +
1350                        sizeof (struct arm_request) +
1351                        sizeof (struct arm_response) +
1352                        2* sizeof (*store));
1353                queue_complete_req(req);
1354        }
1355        spin_unlock(&host_info_lock);
1356        return(rcode);
1357}
1358
1359static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
1360               u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags)
1361{
1362        struct pending_request *req;
1363        struct list_head *lh;
1364        struct host_info *hi;
1365        struct file_info *fi = NULL;
1366        struct list_head *entry;
1367        struct arm_addr  *arm_addr = NULL;
1368        struct arm_request  *arm_req = NULL;
1369        struct arm_response *arm_resp = NULL;
1370        int found=0, size=0, rcode=-1;
1371        octlet_t old, new;
1372        struct arm_request_response *arm_req_resp = NULL;
1373
1374        if (((ext_tcode & 0xFF) == EXTCODE_FETCH_ADD) ||
1375                ((ext_tcode & 0xFF) == EXTCODE_LITTLE_ADD)) {
1376                DBGMSG("arm_lock64 called by node: %X "
1377                      "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X %8.8X ",
1378                      nodeid, (u16) ((addr >>32) & 0xFFFF),
1379                      (u32) (addr & 0xFFFFFFFF), 
1380                      ext_tcode & 0xFF , 
1381                      (u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF), 
1382                      (u32) (be64_to_cpu(data) & 0xFFFFFFFF));
1383        } else {
1384                DBGMSG("arm_lock64 called by node: %X "
1385                      "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X %8.8X arg: "
1386                      "%8.8X %8.8X ",
1387                      nodeid, (u16) ((addr >>32) & 0xFFFF),
1388                      (u32) (addr & 0xFFFFFFFF), 
1389                      ext_tcode & 0xFF , 
1390                      (u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF), 
1391                      (u32) (be64_to_cpu(data) & 0xFFFFFFFF),
1392                      (u32) ((be64_to_cpu(arg)  >> 32) & 0xFFFFFFFF), 
1393                      (u32) (be64_to_cpu(arg)  & 0xFFFFFFFF));
1394        }
1395        spin_lock(&host_info_lock);
1396        hi = find_host_info(host); /* search addressentry in file_info's for host */
1397        if (hi != NULL) {
1398                list_for_each(lh, &hi->file_info_list) {
1399                        fi = list_entry(lh, struct file_info, list);
1400                        entry = fi->addr_list.next;
1401                        while (entry != &(fi->addr_list)) {
1402                                arm_addr = list_entry(entry, struct arm_addr, addr_list);
1403                                if (((arm_addr->start) <= (addr)) && 
1404                                        ((arm_addr->end) >= (addr+sizeof(*store)))) {
1405                                        found = 1;
1406                                        break;
1407                                }
1408                                entry = entry->next;
1409                        }
1410                        if (found) {
1411                                break;
1412                        }
1413                }
1414        }
1415        rcode = -1;
1416        if (!found) {
1417                printk(KERN_ERR "raw1394: arm_lock64 FAILED addr_entry not found"
1418                " -> rcode_address_error\n");
1419                spin_unlock(&host_info_lock);
1420                return (RCODE_ADDRESS_ERROR);
1421        } else {
1422                DBGMSG("arm_lock64 addr_entry FOUND");
1423        }
1424        if (rcode == -1) {
1425                if (arm_addr->access_rights & ARM_LOCK) {
1426                        if (!(arm_addr->client_transactions & ARM_LOCK)) {
1427                                memcpy(&old,(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)),
1428                                        sizeof(old));
1429                                switch (ext_tcode) {
1430                                        case (EXTCODE_MASK_SWAP):
1431                                                new = data | (old & ~arg);
1432                                                break;
1433                                        case (EXTCODE_COMPARE_SWAP):
1434                                                if (old == arg) {
1435                                                        new = data;
1436                                                } else {
1437                                                        new = old;
1438                                                }
1439                                                break;
1440                                        case (EXTCODE_FETCH_ADD):
1441                                                new = cpu_to_be64(be64_to_cpu(data) + be64_to_cpu(old));
1442                                                break;
1443                                        case (EXTCODE_LITTLE_ADD):
1444                                                new = cpu_to_le64(le64_to_cpu(data) + le64_to_cpu(old));
1445                                                break;
1446                                        case (EXTCODE_BOUNDED_ADD):
1447                                                if (old != arg) {
1448                                                        new = cpu_to_be64(be64_to_cpu(data) + 
1449                                                                be64_to_cpu(old));
1450                                                } else {
1451                                                        new = old;
1452                                                }
1453                                                break;
1454                                        case (EXTCODE_WRAP_ADD):
1455                                                if (old != arg) {
1456                                                        new = cpu_to_be64(be64_to_cpu(data) + 
1457                                                                be64_to_cpu(old));
1458                                                } else {
1459                                                        new = data;
1460                                                }
1461                                                break;
1462                                        default:
1463                                                printk(KERN_ERR "raw1394: arm_lock64 FAILED "
1464                                                "ext_tcode not allowed -> rcode_type_error\n");
1465                                                rcode = RCODE_TYPE_ERROR; /* function not allowed */
1466                                                break;
1467                                } /*switch*/
1468                                if (rcode == -1) {
1469                                        DBGMSG("arm_lock64 -> (rcode_complete)");
1470                                        rcode = RCODE_COMPLETE;
1471                                        memcpy (store, &old, sizeof(*store));
1472                                        memcpy ((arm_addr->addr_space_buffer)+
1473                                                (addr-(arm_addr->start)), 
1474                                                &new, sizeof(*store));
1475                                } 
1476                        }
1477                } else {
1478                        rcode = RCODE_TYPE_ERROR; /* function not allowed */
1479                        DBGMSG("arm_lock64 -> rcode_type_error (access denied)");
1480                }
1481        }
1482        if (arm_addr->notification_options & ARM_LOCK) {
1483                DBGMSG("arm_lock64 -> entering notification-section");
1484                req = __alloc_pending_request(SLAB_ATOMIC);
1485                if (!req) {
1486                        spin_unlock(&host_info_lock);
1487                        DBGMSG("arm_lock64 -> rcode_conflict_error");
1488                        return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 
1489                                                        The request may be retried */
1490                }
1491                size =  sizeof(struct arm_request)+sizeof(struct arm_response) +
1492                        3 * sizeof(*store) +
1493                        sizeof (struct arm_request_response); /* maximum */
1494                req->data = kmalloc(size, SLAB_ATOMIC);
1495                if (!(req->data)) {
1496                        free_pending_request(req);
1497                        spin_unlock(&host_info_lock);
1498                        DBGMSG("arm_lock64 -> rcode_conflict_error");
1499                        return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 
1500                                                        The request may be retried */
1501                }
1502                req->free_data=1;
1503                arm_req_resp = (struct arm_request_response *) (req->data);
1504                arm_req  = (struct arm_request *) ((byte_t *)(req->data) + 
1505                        (sizeof (struct arm_request_response)));
1506                arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + 
1507                        (sizeof(struct arm_request)));
1508                arm_req->buffer = ((byte_t *)(arm_resp) + 
1509                        (sizeof(struct arm_response)));
1510                arm_resp->buffer = ((byte_t *)(arm_req->buffer) + 
1511                        (2* sizeof(*store)));
1512                if ((ext_tcode == EXTCODE_FETCH_ADD) || 
1513                        (ext_tcode == EXTCODE_LITTLE_ADD)) {
1514                        arm_req->buffer_length = sizeof(*store);
1515                        memcpy (arm_req->buffer, &data, sizeof(*store));
1516
1517                } else {
1518                        arm_req->buffer_length = 2 * sizeof(*store);
1519                        memcpy (arm_req->buffer, &arg,  sizeof(*store));
1520                        memcpy (((arm_req->buffer) + sizeof(*store)), 
1521                                &data, sizeof(*store));
1522                }
1523                if (rcode == RCODE_COMPLETE) {
1524                        arm_resp->buffer_length = sizeof(*store);
1525                        memcpy (arm_resp->buffer, &old, sizeof(*store));
1526                } else {
1527                        arm_resp->buffer = NULL;
1528                        arm_resp->buffer_length = 0;
1529                }
1530                req->file_info = fi;
1531                req->req.type = RAW1394_REQ_ARM;
1532                req->req.generation = get_hpsb_generation(host);
1533                req->req.misc = ( (((sizeof(*store)) << 16) & (0xFFFF0000)) | 
1534                        (ARM_LOCK & 0xFF));
1535                req->req.tag  = arm_addr->arm_tag;
1536                req->req.recvb = arm_addr->recvb;
1537                req->req.length = size;
1538                arm_req->generation = req->req.generation;
1539                arm_req->extended_transaction_code = ext_tcode;
1540                arm_req->destination_offset = addr;
1541                arm_req->source_nodeid = nodeid;
1542                arm_req->destination_nodeid = host->node_id;
1543                arm_req->tlabel = (flags >> 10) & 0x3f;
1544                arm_req->tcode = (flags >> 4) & 0x0f;
1545                arm_resp->response_code = rcode;
1546                arm_req_resp->request  = int2ptr((arm_addr->recvb) + 
1547                        sizeof (struct arm_request_response));
1548                arm_req_resp->response = int2ptr((arm_addr->recvb) + 
1549                        sizeof (struct arm_request_response) +
1550                        sizeof (struct arm_request));
1551                arm_req->buffer = int2ptr((arm_addr->recvb) + 
1552                        sizeof (struct arm_request_response) +
1553                        sizeof (struct arm_request) +
1554                        sizeof (struct arm_response));
1555                arm_resp->buffer = int2ptr((arm_addr->recvb) + 
1556                        sizeof (struct arm_request_response) +
1557                        sizeof (struct arm_request) +
1558                        sizeof (struct arm_response) +
1559                        2* sizeof (*store));
1560                queue_complete_req(req);
1561        }
1562        spin_unlock(&host_info_lock);
1563        return(rcode);
1564}
1565
1566static int arm_register(struct file_info *fi, struct pending_request *req)
1567{
1568        int retval;
1569        struct arm_addr *addr;
1570        struct list_head *lh, *lh_1, *lh_2;
1571        struct host_info *hi;
1572        struct file_info *fi_hlp = NULL;
1573        struct list_head *entry;
1574        struct arm_addr  *arm_addr = NULL;
1575        int same_host, another_host;
1576        unsigned long flags;
1577
1578        DBGMSG("arm_register called "
1579              "addr(Offset): %8.8x %8.8x length: %u "
1580              "rights: %2.2X notify: %2.2X "
1581              "max_blk_len: %4.4X",
1582              (u32) ((req->req.address >>32) & 0xFFFF),
1583              (u32) (req->req.address & 0xFFFFFFFF),
1584              req->req.length, ((req->req.misc >> 8) & 0xFF),
1585              (req->req.misc & 0xFF),((req->req.misc >> 16) & 0xFFFF));
1586        /* check addressrange */
1587        if ((((req->req.address) & ~(0xFFFFFFFFFFFFULL)) != 0) ||
1588                (((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFFULL)) != 0)) {
1589                req->req.length = 0;
1590                return (-EINVAL);
1591        }
1592        /* addr-list-entry for fileinfo */
1593        addr = (struct arm_addr *)kmalloc(sizeof(struct arm_addr), SLAB_KERNEL); 
1594        if (!addr) {
1595                req->req.length = 0;
1596                return (-ENOMEM);
1597        } 
1598        /* allocation of addr_space_buffer */
1599        addr->addr_space_buffer = (u8 *)vmalloc(req->req.length);
1600        if (!(addr->addr_space_buffer)) {
1601                kfree(addr);
1602                req->req.length = 0;
1603                return (-ENOMEM);
1604        }
1605        /* initialization of addr_space_buffer */
1606        if ((req->req.sendb)== (unsigned long)NULL) {
1607                /* init: set 0 */
1608                memset(addr->addr_space_buffer, 0,req->req.length);
1609        } else {
1610                /* init: user -> kernel */
1611                if (copy_from_user(addr->addr_space_buffer,int2ptr(req->req.sendb),
1612                        req->req.length)) {
1613                        vfree(addr->addr_space_buffer);
1614                        kfree(addr);
1615                        return (-EFAULT);
1616                }
1617        }
1618        INIT_LIST_HEAD(&addr->addr_list);
1619        addr->arm_tag   = req->req.tag;
1620        addr->start     = req->req.address;
1621        addr->end       = req->req.address + req->req.length;
1622        addr->access_rights = (u8) (req->req.misc & 0x0F);
1623        addr->notification_options = (u8) ((req->req.misc >> 4) & 0x0F);
1624        addr->client_transactions = (u8) ((req->req.misc >> 8) & 0x0F);
1625        addr->access_rights |= addr->client_transactions;
1626        addr->notification_options |= addr->client_transactions;
1627        addr->recvb     = req->req.recvb;
1628        addr->rec_length = (u16) ((req->req.misc >> 16) & 0xFFFF);
1629        spin_lock_irqsave(&host_info_lock, flags);
1630        hi = find_host_info(fi->host);
1631        same_host = 0;
1632        another_host = 0;
1633        /* same host with address-entry containing same addressrange ? */
1634        list_for_each(lh, &hi->file_info_list) {
1635                fi_hlp = list_entry(lh, struct file_info, list);
1636                entry = fi_hlp->addr_list.next;
1637                while (entry != &(fi_hlp->addr_list)) {
1638                        arm_addr = list_entry(entry, struct arm_addr, addr_list);
1639                        if ( (arm_addr->start == addr->start) && 
1640                                (arm_addr->end == addr->end)) {
1641                                DBGMSG("same host ownes same "
1642                                        "addressrange -> EALREADY");
1643                                same_host = 1;
1644                                break;
1645                        }
1646                        entry = entry->next;
1647                }
1648                if (same_host) {
1649                        break;
1650                }
1651        }
1652        if (same_host) {
1653                /* addressrange occupied by same host */
1654                vfree(addr->addr_space_buffer);
1655                kfree(addr);
1656                spin_unlock_irqrestore(&host_info_lock, flags);
1657                return (-EALREADY);
1658        }
1659        /* another host with valid address-entry containing same addressrange */
1660        list_for_each(lh_1, &host_info_list) {
1661                hi = list_entry(lh_1, struct host_info, list);
1662                if (hi->host != fi->host) {
1663                        list_for_each(lh_2, &hi->file_info_list) {
1664                                fi_hlp = list_entry(lh_2, struct file_info, list);
1665                                entry = fi_hlp->addr_list.next;
1666                                while (entry != &(fi_hlp->addr_list)) {
1667                                        arm_addr = list_entry(entry, struct arm_addr, addr_list);
1668                                        if ( (arm_addr->start == addr->start) && 
1669                                                (arm_addr->end == addr->end)) {
1670                                                DBGMSG("another host ownes same "
1671                                                "addressrange");
1672                                                another_host = 1;
1673                                                break;
1674                                        }
1675                                        entry = entry->next;
1676                                }
1677                                if (another_host) {
1678                                        break;
1679                                }
1680                        }
1681                }
1682        }
1683        if (another_host) {
1684                DBGMSG("another hosts entry is valid -> SUCCESS");
1685                if (copy_to_user(int2ptr(req->req.recvb),
1686                        int2ptr(&addr->start),sizeof(u64))) {
1687                        printk(KERN_ERR "raw1394: arm_register failed "
1688                              " address-range-entry is invalid -> EFAULT !!!\n");
1689                        vfree(addr->addr_space_buffer);
1690                        kfree(addr);
1691                        spin_unlock_irqrestore(&host_info_lock, flags);
1692                        return (-EFAULT);
1693                }
1694                free_pending_request(req); /* immediate success or fail */
1695                /* INSERT ENTRY */
1696                list_add_tail(&addr->addr_list, &fi->addr_list);
1697                spin_unlock_irqrestore(&host_info_lock, flags);
1698                return sizeof(struct raw1394_request);
1699        }
1700        retval = hpsb_register_addrspace(&raw1394_highlevel, &arm_ops, req->req.address,
1701                req->req.address + req->req.length);
1702        if (retval) {
1703               /* INSERT ENTRY */
1704               list_add_tail(&addr->addr_list, &fi->addr_list);
1705        } else {
1706                DBGMSG("arm_register failed errno: %d \n",retval);
1707                vfree(addr->addr_space_buffer);
1708                kfree(addr);
1709                spin_unlock_irqrestore(&host_info_lock, flags);
1710                return (-EALREADY); 
1711        }
1712        spin_unlock_irqrestore(&host_info_lock, flags);
1713        free_pending_request(req); /* immediate success or fail */
1714        return sizeof(struct raw1394_request);
1715}
1716
1717static int arm_unregister(struct file_info *fi, struct pending_request *req)
1718{
1719        int found  = 0;
1720        int retval = 0;
1721        struct list_head *entry;
1722        struct arm_addr  *addr = NULL;
1723        struct list_head *lh_1, *lh_2;
1724        struct host_info *hi;
1725        struct file_info *fi_hlp = NULL;
1726        struct arm_addr  *arm_addr = NULL;
1727        int another_host;
1728        unsigned long flags;
1729
1730        DBGMSG("arm_Unregister called addr(Offset): "
1731              "%8.8x %8.8x",
1732              (u32) ((req->req.address >>32) & 0xFFFF),
1733              (u32) (req->req.address & 0xFFFFFFFF));
1734        spin_lock_irqsave(&host_info_lock, flags);
1735        /* get addr */
1736        entry = fi->addr_list.next;
1737        while (entry != &(fi->addr_list)) {
1738                addr = list_entry(entry, struct arm_addr, addr_list);
1739                if (addr->start == req->req.address) {
1740                        found = 1;
1741                        break;
1742                }
1743                entry = entry->next;
1744        }
1745        if (!found) {
1746                DBGMSG("arm_Unregister addr not found");
1747                spin_unlock_irqrestore(&host_info_lock, flags);
1748                return (-EINVAL);
1749        }
1750        DBGMSG("arm_Unregister addr found");
1751        another_host = 0;
1752        /* another host with valid address-entry containing 
1753           same addressrange */
1754        list_for_each(lh_1, &host_info_list) {
1755                hi = list_entry(lh_1, struct host_info, list);
1756                if (hi->host != fi->host) {
1757                        list_for_each(lh_2, &hi->file_info_list) {
1758                                fi_hlp = list_entry(lh_2, struct file_info, list);
1759                                entry = fi_hlp->addr_list.next;
1760                                while (entry != &(fi_hlp->addr_list)) {
1761                                        arm_addr = list_entry(entry, 
1762                                                struct arm_addr, addr_list);
1763                                        if (arm_addr->start == 
1764                                                addr->start) {
1765                                                DBGMSG("another host ownes "
1766                                                "same addressrange");
1767                                                another_host = 1;
1768                                                break;
1769                                        }
1770                                        entry = entry->next;
1771                                }
1772                                if (another_host) {
1773                                        break;
1774                                }
1775                        }
1776                }
1777        }
1778        if (another_host) {
1779                DBGMSG("delete entry from list -> success");
1780                list_del(&addr->addr_list);
1781                vfree(addr->addr_space_buffer);
1782                kfree(addr);
1783                free_pending_request(req); /* immediate success or fail */
1784                spin_unlock_irqrestore(&host_info_lock, flags);
1785                return sizeof(struct raw1394_request);
1786        } 
1787        retval = hpsb_unregister_addrspace(&raw1394_highlevel, addr->start);
1788        if (!retval) {
1789                printk(KERN_ERR "raw1394: arm_Unregister failed -> EINVAL\n");
1790                spin_unlock_irqrestore(&host_info_lock, flags);
1791                return (-EINVAL);
1792        }
1793        DBGMSG("delete entry from list -> success");
1794        list_del(&addr->addr_list);
1795        spin_unlock_irqrestore(&host_info_lock, flags);
1796        vfree(addr->addr_space_buffer);
1797        kfree(addr);
1798        free_pending_request(req); /* immediate success or fail */
1799        return sizeof(struct raw1394_request);
1800}
1801
1802static int reset_notification(struct file_info *fi, struct pending_request *req)
1803{
1804        DBGMSG("reset_notification called - switch %s ",
1805                (req->req.misc == RAW1394_NOTIFY_OFF)?"OFF":"ON");
1806        if ((req->req.misc == RAW1394_NOTIFY_OFF) ||
1807                (req->req.misc == RAW1394_NOTIFY_ON)) {
1808                fi->notification=(u8)req->req.misc;
1809                free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
1810                return sizeof(struct raw1394_request);
1811        } 
1812        /* error EINVAL (22) invalid argument */
1813        return (-EINVAL);
1814}
1815
1816static int write_phypacket(struct file_info *fi, struct pending_request *req)
1817{
1818        struct hpsb_packet *packet = NULL;
1819        int retval=0;
1820        quadlet_t data;
1821
1822        data = be32_to_cpu((u32)req->req.sendb);
1823        DBGMSG("write_phypacket called - quadlet 0x%8.8x ",data);
1824        packet = hpsb_make_phypacket (fi->host, data);
1825        if (!packet) return -ENOMEM;
1826        req->req.length=0;
1827        req->packet=packet;
1828        hpsb_set_packet_complete_task(packet, (void(*)(void*))queue_complete_cb, req);
1829        spin_lock_irq(&fi->reqlists_lock);
1830        list_add_tail(&req->list, &fi->req_pending);
1831        spin_unlock_irq(&fi->reqlists_lock);
1832        packet->generation = req->req.generation;
1833        retval = hpsb_send_packet(packet);
1834        DBGMSG("write_phypacket send_packet called => retval: %d ",
1835                retval);
1836        if (! retval) {
1837                req->req.error = RAW1394_ERROR_SEND_ERROR;
1838                req->req.length = 0;
1839                queue_complete_req(req);
1840        }
1841        return sizeof(struct raw1394_request);
1842}
1843
1844static int get_config_rom(struct file_info *fi, struct pending_request *req)
1845{
1846        size_t return_size;
1847        unsigned char rom_version;
1848        int ret=sizeof(struct raw1394_request);
1849        quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL);
1850        int status;
1851        if (!data) return -ENOMEM;
1852        status = hpsb_get_config_rom(fi->host, data, 
1853                req->req.length, &return_size, &rom_version);
1854        if (copy_to_user(int2ptr(req->req.recvb), data, 
1855                req->req.length))
1856                ret = -EFAULT;
1857        if (copy_to_user(int2ptr(req->req.tag), &return_size, 
1858                sizeof(return_size)))
1859                ret = -EFAULT;
1860        if (copy_to_user(int2ptr(req->req.address), &rom_version, 
1861                sizeof(rom_version)))
1862                ret = -EFAULT;
1863        if (copy_to_user(int2ptr(req->req.sendb), &status, 
1864                sizeof(status)))
1865                ret = -EFAULT;
1866        kfree(data);
1867        if (ret >= 0) {
1868                free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
1869        }
1870        return ret;
1871}
1872
1873static int update_config_rom(struct file_info *fi, struct pending_request *req)
1874{
1875        int ret=sizeof(struct raw1394_request);
1876        quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL);
1877        if (!data) return -ENOMEM;
1878        if (copy_from_user(data,int2ptr(req->req.sendb), 
1879                req->req.length)) {
1880                ret= -EFAULT;
1881        } else {
1882                int status = hpsb_update_config_rom(fi->host, 
1883                        data, req->req.length, 
1884                        (unsigned char) req->req.misc);
1885                if (copy_to_user(int2ptr(req->req.recvb), 
1886                        &status, sizeof(status)))
1887                        ret = -ENOMEM;
1888        }
1889        kfree(data);
1890        if (ret >= 0) {
1891                free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
1892        }
1893        return ret;
1894}
1895
1896static int state_connected(struct file_info *fi, struct pending_request *req)
1897{
1898        int node = req->req.address >> 48;
1899
1900        req->req.error = RAW1394_ERROR_NONE;
1901
1902        switch (req->req.type) {
1903
1904        case RAW1394_REQ_ECHO:
1905                queue_complete_req(req);
1906                return sizeof(struct raw1394_request);
1907
1908        case RAW1394_REQ_ISO_SEND:
1909                return handle_iso_send(fi, req, node);
1910
1911        case RAW1394_REQ_ARM_REGISTER:
1912                return arm_register(fi, req);
1913
1914        case RAW1394_REQ_ARM_UNREGISTER:
1915                return arm_unregister(fi, req);
1916
1917        case RAW1394_REQ_RESET_NOTIFY:
1918                return reset_notification(fi, req);
1919
1920        case RAW1394_REQ_ISO_LISTEN:
1921                handle_iso_listen(fi, req);
1922                return sizeof(struct raw1394_request);
1923
1924        case RAW1394_REQ_FCP_LISTEN:
1925                handle_fcp_listen(fi, req);
1926                return sizeof(struct raw1394_request);
1927
1928        case RAW1394_REQ_RESET_BUS:
1929                if (req->req.misc == RAW1394_LONG_RESET) {
1930                        DBGMSG("busreset called (type: LONG)");
1931                        hpsb_reset_bus(fi->host, LONG_RESET);
1932                        free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
1933                        return sizeof(struct raw1394_request);
1934                }
1935                if (req->req.misc == RAW1394_SHORT_RESET) {
1936                        DBGMSG("busreset called (type: SHORT)");
1937                        hpsb_reset_bus(fi->host, SHORT_RESET);
1938                        free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
1939                        return sizeof(struct raw1394_request);
1940                }
1941                /* error EINVAL (22) invalid argument */
1942                return (-EINVAL);
1943        case RAW1394_REQ_GET_ROM:
1944                return get_config_rom(fi, req);
1945
1946        case RAW1394_REQ_UPDATE_ROM:
1947                return update_config_rom(fi, req);
1948        }
1949
1950        if (req->req.generation != get_hpsb_generation(fi->host)) {
1951                req->req.error = RAW1394_ERROR_GENERATION;
1952                req->req.generation = get_hpsb_generation(fi->host);
1953                req->req.length = 0;
1954                queue_complete_req(req);
1955                return sizeof(struct raw1394_request);
1956        }
1957
1958        switch (req->req.type) {
1959        case RAW1394_REQ_PHYPACKET:
1960                return write_phypacket(fi, req);
1961        case RAW1394_REQ_ASYNC_SEND:
1962                return handle_async_send(fi, req);
1963        }
1964
1965        if (req->req.length == 0) {
1966                req->req.error = RAW1394_ERROR_INVALID_ARG;
1967                queue_complete_req(req);
1968                return sizeof(struct raw1394_request);
1969        }
1970
1971        return handle_async_request(fi, req, node);
1972}
1973
1974
1975static ssize_t raw1394_write(struct file *file, const char *buffer, size_t count,
1976                     loff_t *offset_is_ignored)
1977{
1978        struct file_info *fi = (struct file_info *)file->private_data;
1979        struct pending_request *req;
1980        ssize_t retval = 0;
1981
1982        if (count != sizeof(struct raw1394_request)) {
1983                return -EINVAL;
1984        }
1985
1986        req = alloc_pending_request();
1987        if (req == NULL) {
1988                return -ENOMEM;
1989        }
1990        req->file_info = fi;
1991
1992        if (copy_from_user(&req->req, buffer, sizeof(struct raw1394_request))) {
1993                free_pending_request(req);
1994                return -EFAULT;
1995        }
1996
1997        switch (fi->state) {
1998        case opened:
1999                retval = state_opened(fi, req);
2000                break;
2001
2002        case initialized:
2003                retval = state_initialized(fi, req);
2004                break;
2005
2006        case connected:
2007                retval = state_connected(fi, req);
2008                break;
2009        }
2010
2011        if (retval < 0) {
2012                free_pending_request(req);
2013        }
2014
2015        return retval;
2016}
2017
2018/* rawiso operations */
2019
2020/* check if any RAW1394_REQ_RAWISO_ACTIVITY event is already in the
2021 * completion queue (reqlists_lock must be taken) */
2022static inline int __rawiso_event_in_queue(struct file_info *fi)
2023{
2024        struct list_head *lh;
2025        struct pending_request *req;
2026
2027        list_for_each(lh, &fi->req_complete) {
2028                req = list_entry(lh, struct pending_request, list);
2029                if (req->req.type == RAW1394_REQ_RAWISO_ACTIVITY) {
2030                        return 1;
2031                }
2032        }
2033
2034        return 0;
2035}
2036
2037/* put a RAWISO_ACTIVITY event in the queue, if one isn't there already */
2038static void queue_rawiso_event(struct file_info *fi)
2039{
2040        unsigned long flags;
2041
2042        spin_lock_irqsave(&fi->reqlists_lock, flags);
2043
2044        /* only one ISO activity event may be in the queue */
2045        if (!__rawiso_event_in_queue(fi)) {
2046                struct pending_request *req = __alloc_pending_request(SLAB_ATOMIC);
2047
2048                if (req) {
2049                        req->file_info = fi;
2050                        req->req.type = RAW1394_REQ_RAWISO_ACTIVITY;
2051                        req->req.generation = get_hpsb_generation(fi->host);
2052                        __queue_complete_req(req);
2053                } else {
2054                        /* on allocation failure, signal an overflow */
2055                        if (fi->iso_handle) {
2056                                atomic_inc(&fi->iso_handle->overflows);
2057                        }
2058                }
2059        }
2060        spin_unlock_irqrestore(&fi->reqlists_lock, flags);
2061}
2062
2063static void rawiso_activity_cb(struct hpsb_iso *iso)
2064{
2065        unsigned long flags;
2066        struct list_head *lh;
2067        struct host_info *hi;
2068
2069        spin_lock_irqsave(&host_info_lock, flags);
2070        hi = find_host_info(iso->host);
2071
2072        if (hi != NULL) {
2073                list_for_each(lh, &hi->file_info_list) {
2074                        struct file_info *fi = list_entry(lh, struct file_info, list);
2075                        if (fi->iso_handle == iso)
2076                                queue_rawiso_event(fi);
2077                }
2078        }
2079
2080        spin_unlock_irqrestore(&host_info_lock, flags);
2081}
2082
2083/* helper function - gather all the kernel iso status bits for returning to user-space */
2084static void raw1394_iso_fill_status(struct hpsb_iso *iso, struct raw1394_iso_status *stat)
2085{
2086        stat->config.data_buf_size = iso->buf_size;
2087        stat->config.buf_packets = iso->buf_packets;
2088        stat->config.channel = iso->channel;
2089        stat->config.speed = iso->speed;
2090        stat->config.irq_interval = iso->irq_interval;
2091        stat->n_packets = hpsb_iso_n_ready(iso);
2092        stat->overflows = atomic_read(&iso->overflows);
2093        stat->xmit_cycle = iso->xmit_cycle;
2094}
2095
2096static int raw1394_iso_xmit_init(struct file_info *fi, void *uaddr)
2097{
2098        struct raw1394_iso_status stat;
2099
2100        if (!fi->host)
2101                return -EINVAL;
2102
2103        if (copy_from_user(&stat, uaddr, sizeof(stat)))
2104                return -EFAULT;
2105
2106        fi->iso_handle = hpsb_iso_xmit_init(fi->host,
2107                                            stat.config.data_buf_size,
2108                                            stat.config.buf_packets,
2109                                            stat.config.channel,
2110                                            stat.config.speed,
2111                                            stat.config.irq_interval,
2112                                            rawiso_activity_cb);
2113        if (!fi->iso_handle)
2114                return -ENOMEM;
2115
2116        fi->iso_state = RAW1394_ISO_XMIT;
2117
2118        raw1394_iso_fill_status(fi->iso_handle, &stat);
2119        if (copy_to_user(uaddr, &stat, sizeof(stat)))
2120                return -EFAULT;
2121
2122        /* queue an event to get things started */
2123        rawiso_activity_cb(fi->iso_handle);
2124
2125        return 0;
2126}
2127
2128static int raw1394_iso_recv_init(struct file_info *fi, void *uaddr)
2129{
2130        struct raw1394_iso_status stat;
2131
2132        if (!fi->host)
2133                return -EINVAL;
2134
2135        if (copy_from_user(&stat, uaddr, sizeof(stat)))
2136                return -EFAULT;
2137
2138        fi->iso_handle = hpsb_iso_recv_init(fi->host,
2139                                            stat.config.data_buf_size,
2140                                            stat.config.buf_packets,
2141                                            stat.config.channel,
2142                                            stat.config.irq_interval,
2143                                            rawiso_activity_cb);
2144        if (!fi->iso_handle)
2145                return -ENOMEM;
2146
2147        fi->iso_state = RAW1394_ISO_RECV;
2148
2149        raw1394_iso_fill_status(fi->iso_handle, &stat);
2150        if (copy_to_user(uaddr, &stat, sizeof(stat)))
2151                return -EFAULT;
2152        return 0;
2153}
2154
2155static int raw1394_iso_get_status(struct file_info *fi, void *uaddr)
2156{
2157        struct raw1394_iso_status stat;
2158        struct hpsb_iso *iso = fi->iso_handle;
2159
2160        raw1394_iso_fill_status(fi->iso_handle, &stat);
2161        if (copy_to_user(uaddr, &stat, sizeof(stat)))
2162                return -EFAULT;
2163
2164        /* reset overflow counter */
2165        atomic_set(&iso->overflows, 0);
2166
2167        return 0;
2168}
2169
2170/* copy N packet_infos out of the ringbuffer into user-supplied array */
2171static int raw1394_iso_recv_packets(struct file_info *fi, void *uaddr)
2172{
2173        struct raw1394_iso_packets upackets;
2174        unsigned int packet = fi->iso_handle->first_packet;
2175        int i;
2176
2177        if (copy_from_user(&upackets, uaddr, sizeof(upackets)))
2178                return -EFAULT;
2179
2180        if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle))
2181                return -EINVAL;
2182
2183        /* ensure user-supplied buffer is accessible and big enough */
2184        if (verify_area(VERIFY_WRITE, upackets.infos,
2185                       upackets.n_packets * sizeof(struct raw1394_iso_packet_info)))
2186                return -EFAULT;
2187
2188        /* copy the packet_infos out */
2189        for (i = 0; i < upackets.n_packets; i++) {
2190                if (__copy_to_user(&upackets.infos[i],
2191                                  &fi->iso_handle->infos[packet],
2192                                  sizeof(struct raw1394_iso_packet_info)))
2193                        return -EFAULT;
2194                
2195                packet = (packet + 1) % fi->iso_handle->buf_packets;
2196        }
2197
2198        return 0;
2199}
2200
2201/* copy N packet_infos from user to ringbuffer, and queue them for transmission */
2202static int raw1394_iso_send_packets(struct file_info *fi, void *uaddr)
2203{
2204        struct raw1394_iso_packets upackets;
2205        int i, rv;
2206
2207        if (copy_from_user(&upackets, uaddr, sizeof(upackets)))
2208                return -EFAULT;
2209
2210        if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle))
2211                return -EINVAL;
2212
2213        /* ensure user-supplied buffer is accessible and big enough */
2214        if (verify_area(VERIFY_READ, upackets.infos,
2215                       upackets.n_packets * sizeof(struct raw1394_iso_packet_info)))
2216                return -EFAULT;
2217
2218        /* copy the infos structs in and queue the packets */
2219        for (i = 0; i < upackets.n_packets; i++) {
2220                struct raw1394_iso_packet_info info;
2221
2222                if (__copy_from_user(&info, &upackets.infos[i],
2223                                    sizeof(struct raw1394_iso_packet_info)))
2224                        return -EFAULT;
2225
2226                rv = hpsb_iso_xmit_queue_packet(fi->iso_handle, info.offset,
2227                                                info.len, info.tag, info.sy);
2228                if (rv)
2229                        return rv;
2230        }
2231
2232        return 0;
2233}
2234
2235static void raw1394_iso_shutdown(struct file_info *fi)
2236{
2237        if (fi->iso_handle)
2238                hpsb_iso_shutdown(fi->iso_handle);
2239
2240        fi->iso_handle = NULL;
2241        fi->iso_state = RAW1394_ISO_INACTIVE;
2242}
2243
2244/* mmap the rawiso xmit/recv buffer */
2245static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
2246{
2247        struct file_info *fi = file->private_data;
2248
2249        if (fi->iso_state == RAW1394_ISO_INACTIVE)
2250                return -EINVAL;
2251
2252        return dma_region_mmap(&fi->iso_handle->data_buf, file, vma);
2253}
2254
2255/* ioctl is only used for rawiso operations */
2256static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
2257{
2258        struct file_info *fi = file->private_data;
2259
2260        switch(fi->iso_state) {
2261        case RAW1394_ISO_INACTIVE:
2262                switch(cmd) {
2263                case RAW1394_IOC_ISO_XMIT_INIT:
2264                        return raw1394_iso_xmit_init(fi, (void*) arg);
2265                case RAW1394_IOC_ISO_RECV_INIT:
2266                        return raw1394_iso_recv_init(fi, (void*) arg);
2267                default:
2268                        break;
2269                }
2270                break;
2271        case RAW1394_ISO_RECV:
2272                switch(cmd) {
2273                case RAW1394_IOC_ISO_RECV_START: {
2274                        /* copy args from user-space */
2275                        int args[3];
2276                        if (copy_from_user(&args[0], (void*) arg, sizeof(args)))
2277                                return -EFAULT;
2278                        return hpsb_iso_recv_start(fi->iso_handle, args[0], args[1], args[2]);
2279                }
2280                case RAW1394_IOC_ISO_XMIT_RECV_STOP:
2281                        hpsb_iso_stop(fi->iso_handle);
2282                        return 0;
2283                case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
2284                        return hpsb_iso_recv_listen_channel(fi->iso_handle, arg);
2285                case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
2286                        return hpsb_iso_recv_unlisten_channel(fi->iso_handle, arg);
2287                case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: {
2288                        /* copy the u64 from user-space */
2289                        u64 mask;
2290                        if (copy_from_user(&mask, (void*) arg, sizeof(mask)))
2291                                return -EFAULT;
2292                        return hpsb_iso_recv_set_channel_mask(fi->iso_handle, mask);
2293                }
2294                case RAW1394_IOC_ISO_GET_STATUS:
2295                        return raw1394_iso_get_status(fi, (void*) arg);
2296                case RAW1394_IOC_ISO_RECV_PACKETS:
2297                        return raw1394_iso_recv_packets(fi, (void*) arg);
2298                case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
2299                        return hpsb_iso_recv_release_packets(fi->iso_handle, arg);
2300                case RAW1394_IOC_ISO_RECV_FLUSH:
2301                        return hpsb_iso_recv_flush(fi->iso_handle);
2302                case RAW1394_IOC_ISO_SHUTDOWN:
2303                        raw1394_iso_shutdown(fi);
2304                        return 0;
2305                case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2306                        queue_rawiso_event(fi);
2307                        return 0;
2308                }
2309                break;
2310        case RAW1394_ISO_XMIT:
2311                switch(cmd) {
2312                case RAW1394_IOC_ISO_XMIT_START: {
2313                        /* copy two ints from user-space */
2314                        int args[2];
2315                        if (copy_from_user(&args[0], (void*) arg, sizeof(args)))
2316                                return -EFAULT;
2317                        return hpsb_iso_xmit_start(fi->iso_handle, args[0], args[1]);
2318                }
2319                case RAW1394_IOC_ISO_XMIT_SYNC:
2320                        return hpsb_iso_xmit_sync(fi->iso_handle);
2321                case RAW1394_IOC_ISO_XMIT_RECV_STOP:
2322                        hpsb_iso_stop(fi->iso_handle);
2323                        return 0;
2324                case RAW1394_IOC_ISO_GET_STATUS:
2325                        return raw1394_iso_get_status(fi, (void*) arg);
2326                case RAW1394_IOC_ISO_XMIT_PACKETS:
2327                        return raw1394_iso_send_packets(fi, (void*) arg);
2328                case RAW1394_IOC_ISO_SHUTDOWN:
2329                        raw1394_iso_shutdown(fi);
2330                        return 0;
2331                case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2332                        queue_rawiso_event(fi);
2333                        return 0;
2334                }
2335                break;
2336        default:
2337                break;
2338        }
2339
2340        return -EINVAL;
2341}
2342
2343static unsigned int raw1394_poll(struct file *file, poll_table *pt)
2344{
2345        struct file_info *fi = file->private_data;
2346        unsigned int mask = POLLOUT | POLLWRNORM;
2347
2348        poll_wait(file, &fi->poll_wait_complete, pt);
2349
2350        spin_lock_irq(&fi->reqlists_lock);
2351        if (!list_empty(&fi->req_complete)) {
2352                mask |= POLLIN | POLLRDNORM;
2353        }
2354        spin_unlock_irq(&fi->reqlists_lock);
2355
2356        return mask;
2357}
2358
2359static int raw1394_open(struct inode *inode, struct file *file)
2360{
2361        struct file_info *fi;
2362
2363        if (ieee1394_file_to_instance(file) > 0) {
2364                return -ENXIO;
2365        }
2366
2367        fi = kmalloc(sizeof(struct file_info), SLAB_KERNEL);
2368        if (fi == NULL)
2369                return -ENOMEM;
2370        
2371        memset(fi, 0, sizeof(struct file_info));
2372        fi->notification = (u8) RAW1394_NOTIFY_ON; /* busreset notification */
2373
2374        INIT_LIST_HEAD(&fi->list);
2375        fi->state = opened;
2376        INIT_LIST_HEAD(&fi->req_pending);
2377        INIT_LIST_HEAD(&fi->req_complete);
2378        sema_init(&fi->complete_sem, 0);
2379        spin_lock_init(&fi->reqlists_lock);
2380        init_waitqueue_head(&fi->poll_wait_complete);
2381        INIT_LIST_HEAD(&fi->addr_list);
2382
2383        file->private_data = fi;
2384
2385        return 0;
2386}
2387
2388static int raw1394_release(struct inode *inode, struct file *file)
2389{
2390        struct file_info *fi = file->private_data;
2391        struct list_head *lh;
2392        struct pending_request *req;
2393        int done = 0, i, fail = 0;
2394        int retval = 0;
2395        struct list_head *entry;
2396        struct arm_addr  *addr = NULL;
2397        struct list_head *lh_1, *lh_2;
2398        struct host_info *hi;
2399        struct file_info *fi_hlp = NULL;
2400        struct arm_addr  *arm_addr = NULL;
2401        int another_host;
2402
2403        if (fi->iso_state != RAW1394_ISO_INACTIVE)
2404                raw1394_iso_shutdown(fi);
2405
2406        for (i = 0; i < 64; i++) {
2407                if (fi->listen_channels & (1ULL << i)) {
2408                        hpsb_unlisten_channel(&raw1394_highlevel, fi->host, i);
2409                }
2410        }
2411
2412        spin_lock_irq(&host_info_lock);
2413        fi->listen_channels = 0;
2414        spin_unlock_irq(&host_info_lock);
2415
2416        fail = 0;
2417        /* set address-entries invalid */
2418        spin_lock_irq(&host_info_lock);
2419
2420        while (!list_empty(&fi->addr_list)) {
2421                another_host = 0;
2422                lh = fi->addr_list.next;
2423                addr = list_entry(lh, struct arm_addr, addr_list);
2424                /* another host with valid address-entry containing 
2425                   same addressrange? */
2426                list_for_each(lh_1, &host_info_list) {
2427                        hi = list_entry(lh_1, struct host_info, list);
2428                        if (hi->host != fi->host) {
2429                                list_for_each(lh_2, &hi->file_info_list) {
2430                                        fi_hlp = list_entry(lh_2, struct file_info, list);
2431                                        entry = fi_hlp->addr_list.next;
2432                                        while (entry != &(fi_hlp->addr_list)) {
2433                                                arm_addr = list_entry(entry, 
2434                                                        struct arm_addr, addr_list);
2435                                                if (arm_addr->start == 
2436                                                        addr->start) {
2437                                                        DBGMSG("raw1394_release: "
2438                                                        "another host ownes "
2439                                                        "same addressrange");
2440                                                        another_host = 1;
2441                                                        break;
2442                                                }
2443                                                entry = entry->next;
2444                                        }
2445                                        if (another_host) {
2446                                                break;
2447                                        }
2448                                }
2449                        }
2450                }
2451                if (!another_host) {
2452                        DBGMSG("raw1394_release: call hpsb_arm_unregister");
2453                        retval = hpsb_unregister_addrspace(&raw1394_highlevel, addr->start);
2454                        if (!retval) {
2455                                ++fail;
2456                                printk(KERN_ERR "raw1394_release arm_Unregister failed\n");
2457                        }
2458                }
2459                DBGMSG("raw1394_release: delete addr_entry from list");
2460                list_del(&addr->addr_list);
2461                vfree(addr->addr_space_buffer);
2462                kfree(addr);
2463        } /* while */
2464        spin_unlock_irq(&host_info_lock);
2465        if (fail > 0) {
2466                printk(KERN_ERR "raw1394: during addr_list-release "
2467                        "error(s) occurred \n");
2468        }
2469
2470        while (!done) {
2471                spin_lock_irq(&fi->reqlists_lock);
2472
2473                while (!list_empty(&fi->req_complete)) {
2474                        lh = fi->req_complete.next;
2475                        list_del(lh);
2476
2477                        req = list_entry(lh, struct pending_request, list);
2478
2479                        free_pending_request(req);
2480                }
2481
2482                if (list_empty(&fi->req_pending)) done = 1;
2483
2484                spin_unlock_irq(&fi->reqlists_lock);
2485
2486                if (!done) down_interruptible(&fi->complete_sem);
2487        }
2488
2489        if (fi->state == connected) {
2490                spin_lock_irq(&host_info_lock);
2491                list_del(&fi->list);
2492                spin_unlock_irq(&host_info_lock);
2493
2494                hpsb_unref_host(fi->host);
2495        }
2496
2497        kfree(fi);
2498
2499        return 0;
2500}
2501
2502
2503/*** HOTPLUG STUFF **********************************************************/
2504/*
2505 * Export information about protocols/devices supported by this driver.
2506 */
2507static struct ieee1394_device_id raw1394_id_table[] = {
2508        {
2509                .match_flags    = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
2510                .specifier_id   = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
2511                .version        = AVC_SW_VERSION_ENTRY & 0xffffff
2512        },
2513        {
2514                .match_flags    = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
2515                .specifier_id   = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
2516                .version        = CAMERA_SW_VERSION_ENTRY & 0xffffff
2517        },
2518        { }
2519};
2520
2521MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
2522
2523static struct hpsb_protocol_driver raw1394_driver = {
2524        .name =         "raw1394 Driver",
2525        .id_table =     raw1394_id_table,
2526};
2527
2528
2529/******************************************************************************/
2530
2531
2532static struct hpsb_highlevel raw1394_highlevel = {
2533        .name =         RAW1394_DEVICE_NAME,
2534        .add_host =    add_host,
2535        .remove_host = remove_host,
2536        .host_reset =  host_reset,
2537        .iso_receive = iso_receive,
2538        .fcp_request = fcp_request,
2539};
2540
2541static struct file_operations file_ops = {
2542        .owner =        THIS_MODULE,
2543        .read =         raw1394_read, 
2544        .write =        raw1394_write,
2545        .mmap =         raw1394_mmap,
2546        .ioctl =        raw1394_ioctl,
2547        .poll =         raw1394_poll, 
2548        .open =         raw1394_open, 
2549        .release =      raw1394_release, 
2550};
2551
2552static int __init init_raw1394(void)
2553{
2554        hpsb_register_highlevel(&raw1394_highlevel);
2555
2556        devfs_handle = devfs_register(NULL,
2557                                      RAW1394_DEVICE_NAME, DEVFS_FL_NONE,
2558                                      IEEE1394_MAJOR,
2559                                      IEEE1394_MINOR_BLOCK_RAW1394 * 16,
2560                                      S_IFCHR | S_IRUSR | S_IWUSR, &file_ops,
2561                                      NULL);
2562
2563        if (ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_RAW1394,
2564                                      THIS_MODULE, &file_ops)) {
2565                HPSB_ERR("raw1394 failed to register minor device block");
2566                devfs_unregister(devfs_handle);
2567                hpsb_unregister_highlevel(&raw1394_highlevel);
2568                return -EBUSY;
2569        }
2570
2571        printk(KERN_INFO "raw1394: /dev/%s device initialized\n", RAW1394_DEVICE_NAME);
2572
2573        hpsb_register_protocol(&raw1394_driver);
2574
2575        return 0;
2576}
2577
2578static void __exit cleanup_raw1394(void)
2579{
2580        hpsb_unregister_protocol(&raw1394_driver);
2581        ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_RAW1394);
2582        devfs_unregister(devfs_handle);
2583        hpsb_unregister_highlevel(&raw1394_highlevel);
2584}
2585
2586module_init(init_raw1394);
2587module_exit(cleanup_raw1394);
2588MODULE_LICENSE("GPL");
2589
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.