OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [ieee1394/] [ieee1394_core.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
 */
50
MODULE_PARM(disable_nodemgr, "i");
51
MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
52
static int disable_nodemgr = 0;
53
 
54
/* We are GPL, so treat us special */
55
MODULE_LICENSE("GPL");
56
 
57
static kmem_cache_t *hpsb_packet_cache;
58
 
59
/* Some globals used */
60
const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
61
 
62
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
63
static 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
 
79
static 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
 */
101
void 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
 */
130
struct 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
 */
172
void 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
 
181
int 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
 
192
int 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
 */
218
static 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
 
281
static 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
 
355
void 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
 
366
void 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
 
413
void 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
 */
455
int 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
 
495
fail:
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
 */
515
int 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
 
586
static void send_packet_nocare(struct hpsb_packet *packet)
587
{
588
        if (!hpsb_send_packet(packet)) {
589
                free_hpsb_packet(packet);
590
        }
591
}
592
 
593
 
594
void 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
 
675
static 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
 
711
static 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
 
720
static 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
 
732
static 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
 
740
static 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
 
756
static 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
 
887
void 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
 
934
void 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
 
958
void 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
 
1002
static struct {
1003
        struct file_operations *file_ops;
1004
        struct module *module;
1005
} ieee1394_chardevs[16];
1006
 
1007
static rwlock_t ieee1394_chardevs_lock = RW_LOCK_UNLOCKED;
1008
 
1009
static int ieee1394_dispatch_open(struct inode *inode, struct file *file);
1010
 
1011
static struct file_operations ieee1394_chardev_ops = {
1012
        .owner =THIS_MODULE,
1013
        .open = ieee1394_dispatch_open,
1014
};
1015
 
1016
devfs_handle_t ieee1394_devfs_handle;
1017
 
1018
 
1019
/* claim a block of minor numbers */
1020
int 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 */
1048
void 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
 
1074
static 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
 
1098
out:
1099
        read_unlock(&ieee1394_chardevs_lock);
1100
        return ret;
1101
}
1102
 
1103
/* the point of entry for open() on any ieee1394 character device */
1104
static 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
 
1187
struct proc_dir_entry *ieee1394_procfs_entry;
1188
 
1189
static 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
 
1225
static 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
 
1241
module_init(ieee1394_init);
1242
module_exit(ieee1394_cleanup);
1243
 
1244
/* Exported symbols */
1245
 
1246
/** hosts.c **/
1247
EXPORT_SYMBOL(hpsb_alloc_host);
1248
EXPORT_SYMBOL(hpsb_add_host);
1249
EXPORT_SYMBOL(hpsb_remove_host);
1250
EXPORT_SYMBOL(hpsb_ref_host);
1251
EXPORT_SYMBOL(hpsb_unref_host);
1252
 
1253
/** ieee1394_core.c **/
1254
EXPORT_SYMBOL(hpsb_speedto_str);
1255
EXPORT_SYMBOL(hpsb_set_packet_complete_task);
1256
EXPORT_SYMBOL(alloc_hpsb_packet);
1257
EXPORT_SYMBOL(free_hpsb_packet);
1258
EXPORT_SYMBOL(hpsb_send_phy_config);
1259
EXPORT_SYMBOL(hpsb_send_packet);
1260
EXPORT_SYMBOL(hpsb_reset_bus);
1261
EXPORT_SYMBOL(hpsb_bus_reset);
1262
EXPORT_SYMBOL(hpsb_selfid_received);
1263
EXPORT_SYMBOL(hpsb_selfid_complete);
1264
EXPORT_SYMBOL(hpsb_packet_sent);
1265
EXPORT_SYMBOL(hpsb_packet_received);
1266
EXPORT_SYMBOL(ieee1394_register_chardev);
1267
EXPORT_SYMBOL(ieee1394_unregister_chardev);
1268
EXPORT_SYMBOL(ieee1394_devfs_handle);
1269
EXPORT_SYMBOL(ieee1394_procfs_entry);
1270
 
1271
/** ieee1394_transactions.c **/
1272
EXPORT_SYMBOL(hpsb_get_tlabel);
1273
EXPORT_SYMBOL(hpsb_free_tlabel);
1274
EXPORT_SYMBOL(hpsb_make_readpacket);
1275
EXPORT_SYMBOL(hpsb_make_writepacket);
1276
EXPORT_SYMBOL(hpsb_make_streampacket);
1277
EXPORT_SYMBOL(hpsb_make_lockpacket);
1278
EXPORT_SYMBOL(hpsb_make_lock64packet);
1279
EXPORT_SYMBOL(hpsb_make_phypacket);
1280
EXPORT_SYMBOL(hpsb_make_isopacket);
1281
EXPORT_SYMBOL(hpsb_read);
1282
EXPORT_SYMBOL(hpsb_write);
1283
EXPORT_SYMBOL(hpsb_lock);
1284
EXPORT_SYMBOL(hpsb_lock64);
1285
EXPORT_SYMBOL(hpsb_send_gasp);
1286
EXPORT_SYMBOL(hpsb_packet_success);
1287
 
1288
/** highlevel.c **/
1289
EXPORT_SYMBOL(hpsb_register_highlevel);
1290
EXPORT_SYMBOL(hpsb_unregister_highlevel);
1291
EXPORT_SYMBOL(hpsb_register_addrspace);
1292
EXPORT_SYMBOL(hpsb_unregister_addrspace);
1293
EXPORT_SYMBOL(hpsb_listen_channel);
1294
EXPORT_SYMBOL(hpsb_unlisten_channel);
1295
EXPORT_SYMBOL(hpsb_get_hostinfo);
1296
EXPORT_SYMBOL(hpsb_get_host_bykey);
1297
EXPORT_SYMBOL(hpsb_create_hostinfo);
1298
EXPORT_SYMBOL(hpsb_destroy_hostinfo);
1299
EXPORT_SYMBOL(hpsb_set_hostinfo_key);
1300
EXPORT_SYMBOL(hpsb_get_hostinfo_key);
1301
EXPORT_SYMBOL(hpsb_get_hostinfo_bykey);
1302
EXPORT_SYMBOL(hpsb_set_hostinfo);
1303
EXPORT_SYMBOL(highlevel_read);
1304
EXPORT_SYMBOL(highlevel_write);
1305
EXPORT_SYMBOL(highlevel_lock);
1306
EXPORT_SYMBOL(highlevel_lock64);
1307
EXPORT_SYMBOL(highlevel_add_host);
1308
EXPORT_SYMBOL(highlevel_remove_host);
1309
EXPORT_SYMBOL(highlevel_host_reset);
1310
 
1311
/** nodemgr.c **/
1312
EXPORT_SYMBOL(hpsb_guid_get_entry);
1313
EXPORT_SYMBOL(hpsb_nodeid_get_entry);
1314
EXPORT_SYMBOL(hpsb_node_fill_packet);
1315
EXPORT_SYMBOL(hpsb_node_read);
1316
EXPORT_SYMBOL(hpsb_node_write);
1317
EXPORT_SYMBOL(hpsb_node_lock);
1318
EXPORT_SYMBOL(hpsb_register_protocol);
1319
EXPORT_SYMBOL(hpsb_unregister_protocol);
1320
EXPORT_SYMBOL(hpsb_release_unit_directory);
1321
 
1322
/** csr.c **/
1323
EXPORT_SYMBOL(hpsb_update_config_rom);
1324
EXPORT_SYMBOL(hpsb_get_config_rom);
1325
 
1326
/** dma.c **/
1327
EXPORT_SYMBOL(dma_prog_region_init);
1328
EXPORT_SYMBOL(dma_prog_region_alloc);
1329
EXPORT_SYMBOL(dma_prog_region_free);
1330
EXPORT_SYMBOL(dma_region_init);
1331
EXPORT_SYMBOL(dma_region_alloc);
1332
EXPORT_SYMBOL(dma_region_free);
1333
EXPORT_SYMBOL(dma_region_sync);
1334
EXPORT_SYMBOL(dma_region_mmap);
1335
EXPORT_SYMBOL(dma_region_offset_to_bus);
1336
 
1337
/** iso.c **/
1338
EXPORT_SYMBOL(hpsb_iso_xmit_init);
1339
EXPORT_SYMBOL(hpsb_iso_recv_init);
1340
EXPORT_SYMBOL(hpsb_iso_xmit_start);
1341
EXPORT_SYMBOL(hpsb_iso_recv_start);
1342
EXPORT_SYMBOL(hpsb_iso_recv_listen_channel);
1343
EXPORT_SYMBOL(hpsb_iso_recv_unlisten_channel);
1344
EXPORT_SYMBOL(hpsb_iso_recv_set_channel_mask);
1345
EXPORT_SYMBOL(hpsb_iso_stop);
1346
EXPORT_SYMBOL(hpsb_iso_shutdown);
1347
EXPORT_SYMBOL(hpsb_iso_xmit_queue_packet);
1348
EXPORT_SYMBOL(hpsb_iso_xmit_sync);
1349
EXPORT_SYMBOL(hpsb_iso_recv_release_packets);
1350
EXPORT_SYMBOL(hpsb_iso_n_ready);
1351
EXPORT_SYMBOL(hpsb_iso_packet_sent);
1352
EXPORT_SYMBOL(hpsb_iso_packet_received);
1353
EXPORT_SYMBOL(hpsb_iso_wake);
1354
EXPORT_SYMBOL(hpsb_iso_recv_flush);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.