linux-old/drivers/ieee1394/ieee1394_core.c
<<
>>
Prefs
   1/*
   2 * IEEE 1394 for Linux
   3 *
   4 * Core support: hpsb_packet management, packet handling and forwarding to
   5 *               highlevel or lowlevel code
   6 *
   7 * Copyright (C) 1999, 2000 Andreas E. Bombe
   8 *                     2002 Manfred Weihs <weihs@ict.tuwien.ac.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 *        loopback functionality in hpsb_send_packet
  18 *        allow highlevel drivers to disable automatic response generation
  19 *              and to generate responses themselves (deferred)
  20 *
  21 */
  22
  23#include <linux/config.h>
  24#include <linux/kernel.h>
  25#include <linux/list.h>
  26#include <linux/string.h>
  27#include <linux/init.h>
  28#include <linux/slab.h>
  29#include <linux/interrupt.h>
  30#include <linux/module.h>
  31#include <linux/proc_fs.h>
  32#include <linux/bitops.h>
  33#include <asm/byteorder.h>
  34#include <asm/semaphore.h>
  35
  36#include "ieee1394_types.h"
  37#include "ieee1394.h"
  38#include "hosts.h"
  39#include "ieee1394_core.h"
  40#include "highlevel.h"
  41#include "ieee1394_transactions.h"
  42#include "csr.h"
  43#include "nodemgr.h"
  44#include "dma.h"
  45#include "iso.h"
  46
  47/*
  48 * Disable the nodemgr detection and config rom reading functionality.
  49 */
  50MODULE_PARM(disable_nodemgr, "i");
  51MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
  52static int disable_nodemgr = 0;
  53
  54/* We are GPL, so treat us special */
  55MODULE_LICENSE("GPL");
  56
  57static kmem_cache_t *hpsb_packet_cache;
  58
  59/* Some globals used */
  60const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
  61
  62#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
  63static void dump_packet(const char *text, quadlet_t *data, int size)
  64{
  65        int i;
  66
  67        size /= 4;
  68        size = (size > 4 ? 4 : size);
  69
  70        printk(KERN_DEBUG "ieee1394: %s", text);
  71        for (i = 0; i < size; i++)
  72                printk(" %08x", data[i]);
  73        printk("\n");
  74}
  75#else
  76#define dump_packet(x,y,z)
  77#endif
  78
  79static void run_packet_complete(struct hpsb_packet *packet)
  80{
  81        if (packet->complete_routine != NULL) {
  82                void (*complete_routine)(void*) = packet->complete_routine;
  83                void *complete_data = packet->complete_data;
  84
  85                packet->complete_routine = NULL;
  86                packet->complete_data = NULL;
  87                complete_routine(complete_data);
  88        }
  89        return;
  90}
  91
  92/**
  93 * hpsb_set_packet_complete_task - set the task that runs when a packet
  94 * completes. You cannot call this more than once on a single packet
  95 * before it is sent.
  96 *
  97 * @packet: the packet whose completion we want the task added to
  98 * @routine: function to call
  99 * @data: data (if any) to pass to the above function
 100 */
 101void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
 102                                   void (*routine)(void *), void *data)
 103{
 104        BUG_ON(packet->complete_routine != NULL);
 105        packet->complete_routine = routine;
 106        packet->complete_data = data;
 107        return;
 108}
 109
 110/**
 111 * alloc_hpsb_packet - allocate new packet structure
 112 * @data_size: size of the data block to be allocated
 113 *
 114 * This function allocates, initializes and returns a new &struct hpsb_packet.
 115 * It can be used in interrupt context.  A header block is always included, its
 116 * size is big enough to contain all possible 1394 headers.  The data block is
 117 * only allocated when @data_size is not zero.
 118 *
 119 * For packets for which responses will be received the @data_size has to be big
 120 * enough to contain the response's data block since no further allocation
 121 * occurs at response matching time.
 122 *
 123 * The packet's generation value will be set to the current generation number
 124 * for ease of use.  Remember to overwrite it with your own recorded generation
 125 * number if you can not be sure that your code will not race with a bus reset.
 126 *
 127 * Return value: A pointer to a &struct hpsb_packet or NULL on allocation
 128 * failure.
 129 */
 130struct hpsb_packet *alloc_hpsb_packet(size_t data_size)
 131{
 132        struct hpsb_packet *packet = NULL;
 133        void *data = NULL;
 134
 135        packet = kmem_cache_alloc(hpsb_packet_cache, GFP_ATOMIC);
 136        if (packet == NULL)
 137                return NULL;
 138
 139        memset(packet, 0, sizeof(struct hpsb_packet));
 140        packet->header = packet->embedded_header;
 141
 142        if (data_size) {
 143                data = kmalloc(data_size + 8, GFP_ATOMIC);
 144                if (data == NULL) {
 145                        kmem_cache_free(hpsb_packet_cache, packet);
 146                        return NULL;
 147                }
 148
 149                packet->data = data;
 150                packet->data_size = data_size;
 151        }
 152
 153        INIT_LIST_HEAD(&packet->list);
 154        sema_init(&packet->state_change, 0);
 155        packet->complete_routine = NULL;
 156        packet->complete_data = NULL;
 157        packet->state = hpsb_unused;
 158        packet->generation = -1;
 159        packet->data_be = 1;
 160
 161        return packet;
 162}
 163
 164
 165/**
 166 * free_hpsb_packet - free packet and data associated with it
 167 * @packet: packet to free (is NULL safe)
 168 *
 169 * This function will free packet->data, packet->header and finally the packet
 170 * itself.
 171 */
 172void free_hpsb_packet(struct hpsb_packet *packet)
 173{
 174        if (!packet) return;
 175
 176        kfree(packet->data);
 177        kmem_cache_free(hpsb_packet_cache, packet);
 178}
 179
 180
 181int hpsb_reset_bus(struct hpsb_host *host, int type)
 182{
 183        if (!host->in_bus_reset) {
 184                host->driver->devctl(host, RESET_BUS, type);
 185                return 0;
 186        } else {
 187                return 1;
 188        }
 189}
 190
 191
 192int hpsb_bus_reset(struct hpsb_host *host)
 193{
 194        if (host->in_bus_reset) {
 195                HPSB_NOTICE("%s called while bus reset already in progress",
 196                            __FUNCTION__);
 197                return 1;
 198        }
 199
 200        abort_requests(host);
 201        host->in_bus_reset = 1;
 202        host->irm_id = -1;
 203        host->is_irm = 0;
 204        host->busmgr_id = -1;
 205        host->is_busmgr = 0;
 206        host->is_cycmst = 0;
 207        host->node_count = 0;
 208        host->selfid_count = 0;
 209
 210        return 0;
 211}
 212
 213
 214/*
 215 * Verify num_of_selfids SelfIDs and return number of nodes.  Return zero in
 216 * case verification failed.
 217 */
 218static int check_selfids(struct hpsb_host *host)
 219{
 220        int nodeid = -1;
 221        int rest_of_selfids = host->selfid_count;
 222        struct selfid *sid = (struct selfid *)host->topology_map;
 223        struct ext_selfid *esid;
 224        int esid_seq = 23;
 225
 226        host->nodes_active = 0;
 227
 228        while (rest_of_selfids--) {
 229                if (!sid->extended) {
 230                        nodeid++;
 231                        esid_seq = 0;
 232                        
 233                        if (sid->phy_id != nodeid) {
 234                                HPSB_INFO("SelfIDs failed monotony check with "
 235                                          "%d", sid->phy_id);
 236                                return 0;
 237                        }
 238                        
 239                        if (sid->link_active) {
 240                                host->nodes_active++;
 241                                if (sid->contender)
 242                                        host->irm_id = LOCAL_BUS | sid->phy_id;
 243                        }
 244                } else {
 245                        esid = (struct ext_selfid *)sid;
 246
 247                        if ((esid->phy_id != nodeid) 
 248                            || (esid->seq_nr != esid_seq)) {
 249                                HPSB_INFO("SelfIDs failed monotony check with "
 250                                          "%d/%d", esid->phy_id, esid->seq_nr);
 251                                return 0;
 252                        }
 253                        esid_seq++;
 254                }
 255                sid++;
 256        }
 257        
 258        esid = (struct ext_selfid *)(sid - 1);
 259        while (esid->extended) {
 260                if ((esid->porta == 0x2) || (esid->portb == 0x2)
 261                    || (esid->portc == 0x2) || (esid->portd == 0x2)
 262                    || (esid->porte == 0x2) || (esid->portf == 0x2)
 263                    || (esid->portg == 0x2) || (esid->porth == 0x2)) {
 264                                HPSB_INFO("SelfIDs failed root check on "
 265                                          "extended SelfID");
 266                                return 0;
 267                }
 268                esid--;
 269        }
 270
 271        sid = (struct selfid *)esid;
 272        if ((sid->port0 == 0x2) || (sid->port1 == 0x2) || (sid->port2 == 0x2)) {
 273                        HPSB_INFO("SelfIDs failed root check");
 274                        return 0;
 275        }
 276
 277        host->node_count = nodeid + 1;
 278        return 1;
 279}
 280
 281static void build_speed_map(struct hpsb_host *host, int nodecount)
 282{
 283        u8 speedcap[nodecount];
 284        u8 cldcnt[nodecount];
 285        u8 *map = host->speed_map;
 286        struct selfid *sid;
 287        struct ext_selfid *esid;
 288        int i, j, n;
 289
 290        for (i = 0; i < (nodecount * 64); i += 64) {
 291                for (j = 0; j < nodecount; j++) {
 292                        map[i+j] = IEEE1394_SPEED_MAX;
 293                }
 294        }
 295
 296        for (i = 0; i < nodecount; i++) {
 297                cldcnt[i] = 0;
 298        }
 299
 300        /* find direct children count and speed */
 301        for (sid = (struct selfid *)&host->topology_map[host->selfid_count-1],
 302                     n = nodecount - 1;
 303             (void *)sid >= (void *)host->topology_map; sid--) {
 304                if (sid->extended) {
 305                        esid = (struct ext_selfid *)sid;
 306
 307                        if (esid->porta == 0x3) cldcnt[n]++;
 308                        if (esid->portb == 0x3) cldcnt[n]++;
 309                        if (esid->portc == 0x3) cldcnt[n]++;
 310                        if (esid->portd == 0x3) cldcnt[n]++;
 311                        if (esid->porte == 0x3) cldcnt[n]++;
 312                        if (esid->portf == 0x3) cldcnt[n]++;
 313                        if (esid->portg == 0x3) cldcnt[n]++;
 314                        if (esid->porth == 0x3) cldcnt[n]++;
 315                } else {
 316                        if (sid->port0 == 0x3) cldcnt[n]++;
 317                        if (sid->port1 == 0x3) cldcnt[n]++;
 318                        if (sid->port2 == 0x3) cldcnt[n]++;
 319
 320                        speedcap[n] = sid->speed;
 321                        n--;
 322                }
 323        }
 324
 325        /* set self mapping */
 326        for (i = 0; i < nodecount; i++) {
 327                map[64*i + i] = speedcap[i];
 328        }
 329
 330        /* fix up direct children count to total children count;
 331         * also fix up speedcaps for sibling and parent communication */
 332        for (i = 1; i < nodecount; i++) {
 333                for (j = cldcnt[i], n = i - 1; j > 0; j--) {
 334                        cldcnt[i] += cldcnt[n];
 335                        speedcap[n] = min(speedcap[n], speedcap[i]);
 336                        n -= cldcnt[n] + 1;
 337                }
 338        }
 339
 340        for (n = 0; n < nodecount; n++) {
 341                for (i = n - cldcnt[n]; i <= n; i++) {
 342                        for (j = 0; j < (n - cldcnt[n]); j++) {
 343                                map[j*64 + i] = map[i*64 + j] =
 344                                        min(map[i*64 + j], speedcap[n]);
 345                        }
 346                        for (j = n + 1; j < nodecount; j++) {
 347                                map[j*64 + i] = map[i*64 + j] =
 348                                        min(map[i*64 + j], speedcap[n]);
 349                        }
 350                }
 351        }
 352}
 353
 354
 355void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
 356{
 357        if (host->in_bus_reset) {
 358                HPSB_VERBOSE("Including SelfID 0x%x", sid);
 359                host->topology_map[host->selfid_count++] = sid;
 360        } else {
 361                HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d",
 362                            sid, NODEID_TO_BUS(host->node_id));
 363        }
 364}
 365
 366void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
 367{
 368        if (!host->in_bus_reset)
 369                HPSB_NOTICE("SelfID completion called outside of bus reset!");
 370
 371        host->node_id = LOCAL_BUS | phyid;
 372        host->is_root = isroot;
 373
 374        if (!check_selfids(host)) {
 375                if (host->reset_retries++ < 20) {
 376                        /* selfid stage did not complete without error */
 377                        HPSB_NOTICE("Error in SelfID stage, resetting");
 378                        host->in_bus_reset = 0;
 379                        /* this should work from ohci1394 now... */
 380                        hpsb_reset_bus(host, LONG_RESET);
 381                        return;
 382                } else {
 383                        HPSB_NOTICE("Stopping out-of-control reset loop");
 384                        HPSB_NOTICE("Warning - topology map and speed map will not be valid");
 385                        host->reset_retries = 0;
 386                }
 387        } else {
 388                host->reset_retries = 0;
 389                build_speed_map(host, host->node_count);
 390        }
 391
 392        HPSB_VERBOSE("selfid_complete called with successful SelfID stage "
 393                     "... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id);
 394
 395        /* irm_id is kept up to date by check_selfids() */
 396        if (host->irm_id == host->node_id) {
 397                host->is_irm = 1;
 398        } else {
 399                host->is_busmgr = 0;
 400                host->is_irm = 0;
 401        }
 402
 403        if (isroot) {
 404                host->driver->devctl(host, ACT_CYCLE_MASTER, 1);
 405                host->is_cycmst = 1;
 406        }
 407        atomic_inc(&host->generation);
 408        host->in_bus_reset = 0;
 409        highlevel_host_reset(host);
 410}
 411
 412
 413void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, 
 414                      int ackcode)
 415{
 416        unsigned long flags;
 417
 418        packet->ack_code = ackcode;
 419
 420        if (packet->no_waiter) {
 421                /* must not have a tlabel allocated */
 422                free_hpsb_packet(packet);
 423                return;
 424        }
 425
 426        if (ackcode != ACK_PENDING || !packet->expect_response) {
 427                packet->state = hpsb_complete;
 428                up(&packet->state_change);
 429                up(&packet->state_change);
 430                run_packet_complete(packet);
 431                return;
 432        }
 433
 434        packet->state = hpsb_pending;
 435        packet->sendtime = jiffies;
 436
 437        spin_lock_irqsave(&host->pending_pkt_lock, flags);
 438        list_add_tail(&packet->list, &host->pending_packets);
 439        spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 440
 441        up(&packet->state_change);
 442        mod_timer(&host->timeout, jiffies + host->timeout_interval);
 443}
 444
 445/**
 446 * hpsb_send_phy_config - transmit a PHY configuration packet on the bus
 447 * @host: host that PHY config packet gets sent through
 448 * @rootid: root whose force_root bit should get set (-1 = don't set force_root)
 449 * @gapcnt: gap count value to set (-1 = don't set gap count)
 450 *
 451 * This function sends a PHY config packet on the bus through the specified host.
 452 *
 453 * Return value: 0 for success or error number otherwise.
 454 */
 455int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt)
 456{
 457        struct hpsb_packet *packet;
 458        int retval = 0;
 459
 460        if (rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 ||
 461           (rootid == -1 && gapcnt == -1)) {
 462                HPSB_DEBUG("Invalid Parameter: rootid = %d   gapcnt = %d",
 463                           rootid, gapcnt);
 464                return -EINVAL;
 465        }
 466
 467        packet = alloc_hpsb_packet(0);
 468        if (!packet)
 469                return -ENOMEM;
 470
 471        packet->host = host;
 472        packet->header_size = 8;
 473        packet->data_size = 0;
 474        packet->expect_response = 0;
 475        packet->no_waiter = 0;
 476        packet->type = hpsb_raw;
 477        packet->header[0] = 0;
 478        if (rootid != -1)
 479                packet->header[0] |= rootid << 24 | 1 << 23;
 480        if (gapcnt != -1)
 481                packet->header[0] |= gapcnt << 16 | 1 << 22;
 482
 483        packet->header[1] = ~packet->header[0];
 484
 485        packet->generation = get_hpsb_generation(host);
 486
 487        if (!hpsb_send_packet(packet)) {
 488                retval = -EINVAL;
 489                goto fail;
 490        }
 491
 492        down(&packet->state_change);
 493        down(&packet->state_change);
 494
 495fail:
 496        free_hpsb_packet(packet);
 497
 498        return retval;
 499}
 500
 501/**
 502 * hpsb_send_packet - transmit a packet on the bus
 503 * @packet: packet to send
 504 *
 505 * The packet is sent through the host specified in the packet->host field.
 506 * Before sending, the packet's transmit speed is automatically determined using
 507 * the local speed map when it is an async, non-broadcast packet.
 508 *
 509 * Possibilities for failure are that host is either not initialized, in bus
 510 * reset, the packet's generation number doesn't match the current generation
 511 * number or the host reports a transmit error.
 512 *
 513 * Return value: False (0) on failure, true (1) otherwise.
 514 */
 515int hpsb_send_packet(struct hpsb_packet *packet)
 516{
 517        struct hpsb_host *host = packet->host;
 518
 519        if (host->is_shutdown || host->in_bus_reset
 520            || (packet->generation != get_hpsb_generation(host))) {
 521                return 0;
 522        }
 523
 524        packet->state = hpsb_queued;
 525
 526        if (packet->node_id == host->node_id)
 527        { /* it is a local request, so handle it locally */
 528                quadlet_t *data;
 529                size_t size=packet->data_size+packet->header_size;
 530
 531                data = kmalloc(packet->header_size + packet->data_size, GFP_ATOMIC);
 532                if (!data) {
 533                        HPSB_ERR("unable to allocate memory for concatenating header and data");
 534                        return 0;
 535                }
 536
 537                memcpy(data, packet->header, packet->header_size);
 538
 539                if (packet->data_size)
 540                {
 541                        if (packet->data_be) {
 542                                memcpy(((u8*)data)+packet->header_size, packet->data, packet->data_size);
 543                        } else {
 544                                int i;
 545                                quadlet_t *my_data=(quadlet_t*) ((u8*) data + packet->data_size);
 546                                for (i=0; i < packet->data_size/4; i++) {
 547                                        my_data[i] = cpu_to_be32(packet->data[i]);
 548                                }
 549                        }
 550                }
 551
 552                dump_packet("send packet local:", packet->header,
 553                            packet->header_size);
 554
 555                hpsb_packet_sent(host, packet,  packet->expect_response?ACK_PENDING:ACK_COMPLETE);
 556                hpsb_packet_received(host, data, size, 0);
 557
 558                kfree(data);
 559
 560                return 1;
 561        }
 562
 563        if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {
 564                packet->speed_code =
 565                        host->speed_map[NODEID_TO_NODE(host->node_id) * 64
 566                                       + NODEID_TO_NODE(packet->node_id)];
 567        }
 568
 569        switch (packet->speed_code) {
 570        case 2:
 571                dump_packet("send packet 400:", packet->header,
 572                            packet->header_size);
 573                break;
 574        case 1:
 575                dump_packet("send packet 200:", packet->header,
 576                            packet->header_size);
 577                break;
 578        default:
 579                dump_packet("send packet 100:", packet->header,
 580                            packet->header_size);
 581        }
 582
 583        return host->driver->transmit_packet(host, packet);
 584}
 585
 586static void send_packet_nocare(struct hpsb_packet *packet)
 587{
 588        if (!hpsb_send_packet(packet)) {
 589                free_hpsb_packet(packet);
 590        }
 591}
 592
 593
 594void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,
 595                            size_t size)
 596{
 597        struct hpsb_packet *packet = NULL;
 598        struct list_head *lh;
 599        int tcode_match = 0;
 600        int tlabel;
 601        unsigned long flags;
 602
 603        tlabel = (data[0] >> 10) & 0x3f;
 604
 605        spin_lock_irqsave(&host->pending_pkt_lock, flags);
 606
 607        list_for_each(lh, &host->pending_packets) {
 608                packet = list_entry(lh, struct hpsb_packet, list);
 609                if ((packet->tlabel == tlabel)
 610                    && (packet->node_id == (data[1] >> 16))){
 611                        break;
 612                }
 613        }
 614
 615        if (lh == &host->pending_packets) {
 616                HPSB_DEBUG("unsolicited response packet received - no tlabel match");
 617                dump_packet("contents:", data, 16);
 618                spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 619                return;
 620        }
 621
 622        switch (packet->tcode) {
 623        case TCODE_WRITEQ:
 624        case TCODE_WRITEB:
 625                if (tcode == TCODE_WRITE_RESPONSE) tcode_match = 1;
 626                break;
 627        case TCODE_READQ:
 628                if (tcode == TCODE_READQ_RESPONSE) tcode_match = 1;
 629                break;
 630        case TCODE_READB:
 631                if (tcode == TCODE_READB_RESPONSE) tcode_match = 1;
 632                break;
 633        case TCODE_LOCK_REQUEST:
 634                if (tcode == TCODE_LOCK_RESPONSE) tcode_match = 1;
 635                break;
 636        }
 637
 638        if (!tcode_match || (packet->tlabel != tlabel)
 639            || (packet->node_id != (data[1] >> 16))) {
 640                HPSB_INFO("unsolicited response packet received - tcode mismatch");
 641                dump_packet("contents:", data, 16);
 642
 643                spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 644                return;
 645        }
 646
 647        list_del(&packet->list);
 648
 649        spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 650
 651        /* FIXME - update size fields? */
 652        switch (tcode) {
 653        case TCODE_WRITE_RESPONSE:
 654                memcpy(packet->header, data, 12);
 655                break;
 656        case TCODE_READQ_RESPONSE:
 657                memcpy(packet->header, data, 16);
 658                break;
 659        case TCODE_READB_RESPONSE:
 660                memcpy(packet->header, data, 16);
 661                memcpy(packet->data, data + 4, size - 16);
 662                break;
 663        case TCODE_LOCK_RESPONSE:
 664                memcpy(packet->header, data, 16);
 665                memcpy(packet->data, data + 4, (size - 16) > 8 ? 8 : size - 16);
 666                break;
 667        }
 668
 669        packet->state = hpsb_complete;
 670        up(&packet->state_change);
 671        run_packet_complete(packet);
 672}
 673
 674
 675static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,
 676                                               quadlet_t *data, size_t dsize)
 677{
 678        struct hpsb_packet *p;
 679
 680        dsize += (dsize % 4 ? 4 - (dsize % 4) : 0);
 681
 682        p = alloc_hpsb_packet(dsize);
 683        if (p == NULL) {
 684                /* FIXME - send data_error response */
 685                return NULL;
 686        }
 687
 688        p->type = hpsb_async;
 689        p->state = hpsb_unused;
 690        p->host = host;
 691        p->node_id = data[1] >> 16;
 692        p->tlabel = (data[0] >> 10) & 0x3f;
 693        p->no_waiter = 1;
 694
 695        p->generation = get_hpsb_generation(host);
 696
 697        if (dsize % 4) {
 698                p->data[dsize / 4] = 0;
 699        }
 700
 701        return p;
 702}
 703
 704#define PREP_ASYNC_HEAD_RCODE(tc) \
 705        packet->tcode = tc; \
 706        packet->header[0] = (packet->node_id << 16) | (packet->tlabel << 10) \
 707                | (1 << 8) | (tc << 4); \
 708        packet->header[1] = (packet->host->node_id << 16) | (rcode << 12); \
 709        packet->header[2] = 0
 710
 711static void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode,
 712                              quadlet_t data)
 713{
 714        PREP_ASYNC_HEAD_RCODE(TCODE_READQ_RESPONSE);
 715        packet->header[3] = data;
 716        packet->header_size = 16;
 717        packet->data_size = 0;
 718}
 719
 720static void fill_async_readblock_resp(struct hpsb_packet *packet, int rcode,
 721                               int length)
 722{
 723        if (rcode != RCODE_COMPLETE)
 724                length = 0;
 725
 726        PREP_ASYNC_HEAD_RCODE(TCODE_READB_RESPONSE);
 727        packet->header[3] = length << 16;
 728        packet->header_size = 16;
 729        packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
 730}
 731
 732static void fill_async_write_resp(struct hpsb_packet *packet, int rcode)
 733{
 734        PREP_ASYNC_HEAD_RCODE(TCODE_WRITE_RESPONSE);
 735        packet->header[2] = 0;
 736        packet->header_size = 12;
 737        packet->data_size = 0;
 738}
 739
 740static void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extcode,
 741                          int length)
 742{
 743        if (rcode != RCODE_COMPLETE)
 744                length = 0;
 745
 746        PREP_ASYNC_HEAD_RCODE(TCODE_LOCK_RESPONSE);
 747        packet->header[3] = (length << 16) | extcode;
 748        packet->header_size = 16;
 749        packet->data_size = length;
 750}
 751
 752#define PREP_REPLY_PACKET(length) \
 753                packet = create_reply_packet(host, data, length); \
 754                if (packet == NULL) break
 755
 756static void handle_incoming_packet(struct hpsb_host *host, int tcode,
 757                                   quadlet_t *data, size_t size, int write_acked)
 758{
 759        struct hpsb_packet *packet;
 760        int length, rcode, extcode;
 761        quadlet_t buffer;
 762        nodeid_t source = data[1] >> 16;
 763        nodeid_t dest = data[0] >> 16;
 764        u16 flags = (u16) data[0];
 765        u64 addr;
 766
 767        /* big FIXME - no error checking is done for an out of bounds length */
 768
 769        switch (tcode) {
 770        case TCODE_WRITEQ:
 771                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
 772                rcode = highlevel_write(host, source, dest, data+3,
 773                                        addr, 4, flags);
 774
 775                if (!write_acked
 776                    && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
 777                    && (rcode >= 0)) {
 778                        /* not a broadcast write, reply */
 779                        PREP_REPLY_PACKET(0);
 780                        fill_async_write_resp(packet, rcode);
 781                        send_packet_nocare(packet);
 782                }
 783                break;
 784
 785        case TCODE_WRITEB:
 786                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
 787                rcode = highlevel_write(host, source, dest, data+4,
 788                                        addr, data[3]>>16, flags);
 789
 790                if (!write_acked
 791                    && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
 792                    && (rcode >= 0)) {
 793                        /* not a broadcast write, reply */
 794                        PREP_REPLY_PACKET(0);
 795                        fill_async_write_resp(packet, rcode);
 796                        send_packet_nocare(packet);
 797                }
 798                break;
 799
 800        case TCODE_READQ:
 801                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
 802                rcode = highlevel_read(host, source, &buffer, addr, 4, flags);
 803
 804                if (rcode >= 0) {
 805                        PREP_REPLY_PACKET(0);
 806                        fill_async_readquad_resp(packet, rcode, buffer);
 807                        send_packet_nocare(packet);
 808                }
 809                break;
 810
 811        case TCODE_READB:
 812                length = data[3] >> 16;
 813                PREP_REPLY_PACKET(length);
 814
 815                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
 816                rcode = highlevel_read(host, source, packet->data, addr,
 817                                       length, flags);
 818
 819                if (rcode >= 0) {
 820                        fill_async_readblock_resp(packet, rcode, length);
 821                        send_packet_nocare(packet);
 822                } else {
 823                        free_hpsb_packet(packet);
 824                }
 825                break;
 826
 827        case TCODE_LOCK_REQUEST:
 828                length = data[3] >> 16;
 829                extcode = data[3] & 0xffff;
 830                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
 831
 832                PREP_REPLY_PACKET(8);
 833
 834                if ((extcode == 0) || (extcode >= 7)) {
 835                        /* let switch default handle error */
 836                        length = 0;
 837                }
 838
 839                switch (length) {
 840                case 4:
 841                        rcode = highlevel_lock(host, source, packet->data, addr,
 842                                               data[4], 0, extcode,flags);
 843                        fill_async_lock_resp(packet, rcode, extcode, 4);
 844                        break;
 845                case 8:
 846                        if ((extcode != EXTCODE_FETCH_ADD) 
 847                            && (extcode != EXTCODE_LITTLE_ADD)) {
 848                                rcode = highlevel_lock(host, source,
 849                                                       packet->data, addr,
 850                                                       data[5], data[4], 
 851                                                       extcode, flags);
 852                                fill_async_lock_resp(packet, rcode, extcode, 4);
 853                        } else {
 854                                rcode = highlevel_lock64(host, source,
 855                                             (octlet_t *)packet->data, addr,
 856                                             *(octlet_t *)(data + 4), 0ULL,
 857                                             extcode, flags);
 858                                fill_async_lock_resp(packet, rcode, extcode, 8);
 859                        }
 860                        break;
 861                case 16:
 862                        rcode = highlevel_lock64(host, source,
 863                                                 (octlet_t *)packet->data, addr,
 864                                                 *(octlet_t *)(data + 6),
 865                                                 *(octlet_t *)(data + 4), 
 866                                                 extcode, flags);
 867                        fill_async_lock_resp(packet, rcode, extcode, 8);
 868                        break;
 869                default:
 870                        rcode = RCODE_TYPE_ERROR;
 871                        fill_async_lock_resp(packet, rcode,
 872                                             extcode, 0);
 873                }
 874
 875                if (rcode >= 0) {
 876                        send_packet_nocare(packet);
 877                } else {
 878                        free_hpsb_packet(packet);
 879                }
 880                break;
 881        }
 882
 883}
 884#undef PREP_REPLY_PACKET
 885
 886
 887void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
 888                          int write_acked)
 889{
 890        int tcode;
 891
 892        if (host->in_bus_reset) {
 893                HPSB_INFO("received packet during reset; ignoring");
 894                return;
 895        }
 896
 897        dump_packet("received packet:", data, size);
 898
 899        tcode = (data[0] >> 4) & 0xf;
 900
 901        switch (tcode) {
 902        case TCODE_WRITE_RESPONSE:
 903        case TCODE_READQ_RESPONSE:
 904        case TCODE_READB_RESPONSE:
 905        case TCODE_LOCK_RESPONSE:
 906                handle_packet_response(host, tcode, data, size);
 907                break;
 908
 909        case TCODE_WRITEQ:
 910        case TCODE_WRITEB:
 911        case TCODE_READQ:
 912        case TCODE_READB:
 913        case TCODE_LOCK_REQUEST:
 914                handle_incoming_packet(host, tcode, data, size, write_acked);
 915                break;
 916
 917
 918        case TCODE_ISO_DATA:
 919                highlevel_iso_receive(host, data, size);
 920                break;
 921
 922        case TCODE_CYCLE_START:
 923                /* simply ignore this packet if it is passed on */
 924                break;
 925
 926        default:
 927                HPSB_NOTICE("received packet with bogus transaction code %d", 
 928                            tcode);
 929                break;
 930        }
 931}
 932
 933
 934void abort_requests(struct hpsb_host *host)
 935{
 936        unsigned long flags;
 937        struct hpsb_packet *packet;
 938        struct list_head *lh, *tlh;
 939        LIST_HEAD(llist);
 940
 941        host->driver->devctl(host, CANCEL_REQUESTS, 0);
 942
 943        spin_lock_irqsave(&host->pending_pkt_lock, flags);
 944        list_splice(&host->pending_packets, &llist);
 945        INIT_LIST_HEAD(&host->pending_packets);
 946        spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 947
 948        list_for_each_safe(lh, tlh, &llist) {
 949                packet = list_entry(lh, struct hpsb_packet, list);
 950                list_del(&packet->list);
 951                packet->state = hpsb_complete;
 952                packet->ack_code = ACKX_ABORTED;
 953                up(&packet->state_change);
 954                run_packet_complete(packet);
 955        }
 956}
 957
 958void abort_timedouts(unsigned long __opaque)
 959{
 960        struct hpsb_host *host = (struct hpsb_host *)__opaque;
 961        unsigned long flags;
 962        struct hpsb_packet *packet;
 963        unsigned long expire;
 964        struct list_head *lh, *tlh;
 965        LIST_HEAD(expiredlist);
 966
 967        spin_lock_irqsave(&host->csr.lock, flags);
 968        expire = host->csr.expire;
 969        spin_unlock_irqrestore(&host->csr.lock, flags);
 970
 971        spin_lock_irqsave(&host->pending_pkt_lock, flags);
 972
 973        list_for_each_safe(lh, tlh, &host->pending_packets) {
 974                packet = list_entry(lh, struct hpsb_packet, list);
 975                if (time_before(packet->sendtime + expire, jiffies)) {
 976                        list_del(&packet->list);
 977                        list_add(&packet->list, &expiredlist);
 978                }
 979        }
 980
 981        if (!list_empty(&host->pending_packets))
 982                mod_timer(&host->timeout, jiffies + host->timeout_interval);
 983
 984        spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 985
 986        list_for_each_safe(lh, tlh, &expiredlist) {
 987                packet = list_entry(lh, struct hpsb_packet, list);
 988                list_del(&packet->list);
 989                packet->state = hpsb_complete;
 990                packet->ack_code = ACKX_TIMEOUT;
 991                up(&packet->state_change);
 992                run_packet_complete(packet);
 993        }
 994}
 995
 996
 997/*
 998 * character device dispatching (see ieee1394_core.h)
 999 * Dan Maas <dmaas@dcine.com>
1000 */
1001
1002static struct {
1003        struct file_operations *file_ops;
1004        struct module *module;
1005} ieee1394_chardevs[16];
1006
1007static rwlock_t ieee1394_chardevs_lock = RW_LOCK_UNLOCKED;
1008
1009static int ieee1394_dispatch_open(struct inode *inode, struct file *file);
1010
1011static struct file_operations ieee1394_chardev_ops = {
1012        .owner =THIS_MODULE,
1013        .open = ieee1394_dispatch_open,
1014};
1015
1016devfs_handle_t ieee1394_devfs_handle;
1017
1018
1019/* claim a block of minor numbers */
1020int ieee1394_register_chardev(int blocknum,
1021                              struct module *module,
1022                              struct file_operations *file_ops)
1023{
1024        int retval;
1025
1026        if ( (blocknum < 0) || (blocknum > 15) )
1027                return -EINVAL;
1028
1029        write_lock(&ieee1394_chardevs_lock);
1030
1031        if (ieee1394_chardevs[blocknum].file_ops == NULL) {
1032                /* grab the minor block */
1033                ieee1394_chardevs[blocknum].file_ops = file_ops;
1034                ieee1394_chardevs[blocknum].module = module;
1035                
1036                retval = 0;
1037        } else {
1038                /* block already taken */
1039                retval = -EBUSY;
1040        }
1041
1042        write_unlock(&ieee1394_chardevs_lock);
1043
1044        return retval;
1045}
1046
1047/* release a block of minor numbers */
1048void ieee1394_unregister_chardev(int blocknum)
1049{
1050        if ( (blocknum < 0) || (blocknum > 15) )
1051                return;
1052
1053        write_lock(&ieee1394_chardevs_lock);
1054
1055        if (ieee1394_chardevs[blocknum].file_ops) {
1056                ieee1394_chardevs[blocknum].file_ops = NULL;
1057                ieee1394_chardevs[blocknum].module = NULL;
1058        }
1059
1060        write_unlock(&ieee1394_chardevs_lock);
1061}
1062
1063/*
1064  ieee1394_get_chardev() - look up and acquire a character device
1065  driver that has previously registered using ieee1394_register_chardev()
1066  
1067  On success, returns 1 and sets module and file_ops to the driver.
1068  The module will have an incremented reference count.
1069   
1070  On failure, returns 0.
1071  The module will NOT have an incremented reference count.
1072*/
1073
1074static int ieee1394_get_chardev(int blocknum,
1075                                struct module **module,
1076                                struct file_operations **file_ops)
1077{
1078        int ret = 0;
1079       
1080        if ((blocknum < 0) || (blocknum > 15))
1081                return ret;
1082
1083        read_lock(&ieee1394_chardevs_lock);
1084
1085        *module = ieee1394_chardevs[blocknum].module;
1086        *file_ops = ieee1394_chardevs[blocknum].file_ops;
1087
1088        if (*file_ops == NULL)
1089                goto out;
1090
1091        /* don't need try_inc_mod_count if the driver is non-modular */
1092        if (*module && (try_inc_mod_count(*module) == 0))
1093                goto out;
1094
1095        /* success! */
1096        ret = 1;
1097
1098out:
1099        read_unlock(&ieee1394_chardevs_lock);
1100        return ret;
1101}
1102
1103/* the point of entry for open() on any ieee1394 character device */
1104static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
1105{
1106        struct file_operations *file_ops;
1107        struct module *module;
1108        int blocknum;
1109        int retval;
1110
1111        /*
1112          Maintaining correct module reference counts is tricky here!
1113
1114          The key thing to remember is that the VFS increments the
1115          reference count of ieee1394 before it calls
1116          ieee1394_dispatch_open().
1117
1118          If the open() succeeds, then we need to transfer this extra
1119          reference to the task-specific driver module (e.g. raw1394).
1120          The VFS will deref the driver module automatically when the
1121          file is later released.
1122
1123          If the open() fails, then the VFS will drop the
1124          reference count of whatever module file->f_op->owner points
1125          to, immediately after this function returns.
1126        */
1127
1128        /* shift away lower four bits of the minor
1129           to get the index of the ieee1394_driver
1130           we want */
1131
1132        blocknum = (MINOR(inode->i_rdev) >> 4) & 0xF;
1133
1134        /* look up the driver */
1135
1136        if (ieee1394_get_chardev(blocknum, &module, &file_ops) == 0)
1137                return -ENODEV;
1138
1139        /* redirect all subsequent requests to the driver's
1140           own file_operations */
1141        file->f_op = file_ops;
1142
1143        /* at this point BOTH ieee1394 and the task-specific driver have
1144           an extra reference */
1145
1146        /* follow through with the open() */
1147        retval = file_ops->open(inode, file);
1148
1149        if (retval == 0) {
1150                
1151                /* If the open() succeeded, then ieee1394 will be left
1152                   with an extra module reference, so we discard it here.
1153
1154                   The task-specific driver still has the extra
1155                   reference given to it by ieee1394_get_chardev().
1156                   This extra reference prevents the module from
1157                   unloading while the file is open, and will be
1158                   dropped by the VFS when the file is released.
1159                */
1160                
1161                if (THIS_MODULE)
1162                        __MOD_DEC_USE_COUNT((struct module*) THIS_MODULE);
1163                
1164                /* note that if ieee1394 is compiled into the kernel,
1165                   THIS_MODULE will be (void*) NULL, hence the if and
1166                   the cast are necessary */
1167
1168        } else {
1169
1170                /* if the open() failed, then we need to drop the
1171                   extra reference we gave to the task-specific
1172                   driver */
1173                
1174                if (module)
1175                        __MOD_DEC_USE_COUNT(module);
1176        
1177                /* point the file's f_ops back to ieee1394. The VFS will then
1178                   decrement ieee1394's reference count immediately after this
1179                   function returns. */
1180                
1181                file->f_op = &ieee1394_chardev_ops;
1182        }
1183
1184        return retval;
1185}
1186
1187struct proc_dir_entry *ieee1394_procfs_entry;
1188
1189static int __init ieee1394_init(void)
1190{
1191        hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet),
1192                                              0, 0, NULL, NULL);
1193
1194        ieee1394_devfs_handle = devfs_mk_dir(NULL, "ieee1394", NULL);
1195
1196        if (register_chrdev(IEEE1394_MAJOR, "ieee1394", &ieee1394_chardev_ops)) {
1197                HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR);
1198                devfs_unregister(ieee1394_devfs_handle);
1199                return -ENODEV;
1200        }
1201
1202#ifdef CONFIG_PROC_FS
1203        /* Must be done before we start everything else, since the drivers
1204         * may use it.  */
1205        ieee1394_procfs_entry = proc_mkdir("ieee1394", proc_bus);
1206        if (ieee1394_procfs_entry == NULL) {
1207                HPSB_ERR("unable to create /proc/bus/ieee1394\n");
1208                unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
1209                devfs_unregister(ieee1394_devfs_handle);
1210                return -ENOMEM;
1211        }
1212        ieee1394_procfs_entry->owner = THIS_MODULE;
1213#endif
1214
1215        init_hpsb_highlevel();
1216        init_csr();
1217        if (!disable_nodemgr)
1218                init_ieee1394_nodemgr();
1219        else
1220                HPSB_INFO("nodemgr functionality disabled");
1221
1222        return 0;
1223}
1224
1225static void __exit ieee1394_cleanup(void)
1226{
1227        if (!disable_nodemgr)
1228                cleanup_ieee1394_nodemgr();
1229
1230        cleanup_csr();
1231        kmem_cache_destroy(hpsb_packet_cache);
1232
1233        unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
1234        
1235        /* it's ok to pass a NULL devfs_handle to devfs_unregister */
1236        devfs_unregister(ieee1394_devfs_handle);
1237        
1238        remove_proc_entry("ieee1394", proc_bus);
1239}
1240
1241module_init(ieee1394_init);
1242module_exit(ieee1394_cleanup);
1243
1244/* Exported symbols */
1245
1246/** hosts.c **/
1247EXPORT_SYMBOL(hpsb_alloc_host);
1248EXPORT_SYMBOL(hpsb_add_host);
1249EXPORT_SYMBOL(hpsb_remove_host);
1250EXPORT_SYMBOL(hpsb_ref_host);
1251EXPORT_SYMBOL(hpsb_unref_host);
1252
1253/** ieee1394_core.c **/
1254EXPORT_SYMBOL(hpsb_speedto_str);
1255EXPORT_SYMBOL(hpsb_set_packet_complete_task);
1256EXPORT_SYMBOL(alloc_hpsb_packet);
1257EXPORT_SYMBOL(free_hpsb_packet);
1258EXPORT_SYMBOL(hpsb_send_phy_config);
1259EXPORT_SYMBOL(hpsb_send_packet);
1260EXPORT_SYMBOL(hpsb_reset_bus);
1261EXPORT_SYMBOL(hpsb_bus_reset);
1262EXPORT_SYMBOL(hpsb_selfid_received);
1263EXPORT_SYMBOL(hpsb_selfid_complete);
1264EXPORT_SYMBOL(hpsb_packet_sent);
1265EXPORT_SYMBOL(hpsb_packet_received);
1266EXPORT_SYMBOL(ieee1394_register_chardev);
1267EXPORT_SYMBOL(ieee1394_unregister_chardev);
1268EXPORT_SYMBOL(ieee1394_devfs_handle);
1269EXPORT_SYMBOL(ieee1394_procfs_entry);
1270
1271/** ieee1394_transactions.c **/
1272EXPORT_SYMBOL(hpsb_get_tlabel);
1273EXPORT_SYMBOL(hpsb_free_tlabel);
1274EXPORT_SYMBOL(hpsb_make_readpacket);
1275EXPORT_SYMBOL(hpsb_make_writepacket);
1276EXPORT_SYMBOL(hpsb_make_streampacket);
1277EXPORT_SYMBOL(hpsb_make_lockpacket);
1278EXPORT_SYMBOL(hpsb_make_lock64packet);
1279EXPORT_SYMBOL(hpsb_make_phypacket);
1280EXPORT_SYMBOL(hpsb_make_isopacket);
1281EXPORT_SYMBOL(hpsb_read);
1282EXPORT_SYMBOL(hpsb_write);
1283EXPORT_SYMBOL(hpsb_lock);
1284EXPORT_SYMBOL(hpsb_lock64);
1285EXPORT_SYMBOL(hpsb_send_gasp);
1286EXPORT_SYMBOL(hpsb_packet_success);
1287
1288/** highlevel.c **/
1289EXPORT_SYMBOL(hpsb_register_highlevel);
1290EXPORT_SYMBOL(hpsb_unregister_highlevel);
1291EXPORT_SYMBOL(hpsb_register_addrspace);
1292EXPORT_SYMBOL(hpsb_unregister_addrspace);
1293EXPORT_SYMBOL(hpsb_listen_channel);
1294EXPORT_SYMBOL(hpsb_unlisten_channel);
1295EXPORT_SYMBOL(hpsb_get_hostinfo);
1296EXPORT_SYMBOL(hpsb_get_host_bykey);
1297EXPORT_SYMBOL(hpsb_create_hostinfo);
1298EXPORT_SYMBOL(hpsb_destroy_hostinfo);
1299EXPORT_SYMBOL(hpsb_set_hostinfo_key);
1300EXPORT_SYMBOL(hpsb_get_hostinfo_key);
1301EXPORT_SYMBOL(hpsb_get_hostinfo_bykey);
1302EXPORT_SYMBOL(hpsb_set_hostinfo);
1303EXPORT_SYMBOL(highlevel_read);
1304EXPORT_SYMBOL(highlevel_write);
1305EXPORT_SYMBOL(highlevel_lock);
1306EXPORT_SYMBOL(highlevel_lock64);
1307EXPORT_SYMBOL(highlevel_add_host);
1308EXPORT_SYMBOL(highlevel_remove_host);
1309EXPORT_SYMBOL(highlevel_host_reset);
1310
1311/** nodemgr.c **/
1312EXPORT_SYMBOL(hpsb_guid_get_entry);
1313EXPORT_SYMBOL(hpsb_nodeid_get_entry);
1314EXPORT_SYMBOL(hpsb_node_fill_packet);
1315EXPORT_SYMBOL(hpsb_node_read);
1316EXPORT_SYMBOL(hpsb_node_write);
1317EXPORT_SYMBOL(hpsb_node_lock);
1318EXPORT_SYMBOL(hpsb_register_protocol);
1319EXPORT_SYMBOL(hpsb_unregister_protocol);
1320EXPORT_SYMBOL(hpsb_release_unit_directory);
1321
1322/** csr.c **/
1323EXPORT_SYMBOL(hpsb_update_config_rom);
1324EXPORT_SYMBOL(hpsb_get_config_rom);
1325
1326/** dma.c **/
1327EXPORT_SYMBOL(dma_prog_region_init);
1328EXPORT_SYMBOL(dma_prog_region_alloc);
1329EXPORT_SYMBOL(dma_prog_region_free);
1330EXPORT_SYMBOL(dma_region_init);
1331EXPORT_SYMBOL(dma_region_alloc);
1332EXPORT_SYMBOL(dma_region_free);
1333EXPORT_SYMBOL(dma_region_sync);
1334EXPORT_SYMBOL(dma_region_mmap);
1335EXPORT_SYMBOL(dma_region_offset_to_bus);
1336
1337/** iso.c **/
1338EXPORT_SYMBOL(hpsb_iso_xmit_init);
1339EXPORT_SYMBOL(hpsb_iso_recv_init);
1340EXPORT_SYMBOL(hpsb_iso_xmit_start);
1341EXPORT_SYMBOL(hpsb_iso_recv_start);
1342EXPORT_SYMBOL(hpsb_iso_recv_listen_channel);
1343EXPORT_SYMBOL(hpsb_iso_recv_unlisten_channel);
1344EXPORT_SYMBOL(hpsb_iso_recv_set_channel_mask);
1345EXPORT_SYMBOL(hpsb_iso_stop);
1346EXPORT_SYMBOL(hpsb_iso_shutdown);
1347EXPORT_SYMBOL(hpsb_iso_xmit_queue_packet);
1348EXPORT_SYMBOL(hpsb_iso_xmit_sync);
1349EXPORT_SYMBOL(hpsb_iso_recv_release_packets);
1350EXPORT_SYMBOL(hpsb_iso_n_ready);
1351EXPORT_SYMBOL(hpsb_iso_packet_sent);
1352EXPORT_SYMBOL(hpsb_iso_packet_received);
1353EXPORT_SYMBOL(hpsb_iso_wake);
1354EXPORT_SYMBOL(hpsb_iso_recv_flush);
1355
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.