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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [ieee1394/] [csr.c] - Blame information for rev 65

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

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * IEEE 1394 for Linux
3
 *
4
 * CSR implementation, iso/bus manager implementation.
5
 *
6
 * Copyright (C) 1999 Andreas E. Bombe
7
 *               2002 Manfred Weihs <weihs@ict.tuwien.ac.at>
8
 *
9
 * This code is licensed under the GPL.  See the file COPYING in the root
10
 * directory of the kernel sources for details.
11
 *
12
 *
13
 * Contributions:
14
 *
15
 * Manfred Weihs <weihs@ict.tuwien.ac.at>
16
 *        configuration ROM manipulation
17
 *
18
 */
19
 
20
#include <linux/jiffies.h>
21
#include <linux/kernel.h>
22
#include <linux/module.h>
23
#include <linux/moduleparam.h>
24
#include <linux/param.h>
25
#include <linux/spinlock.h>
26
#include <linux/string.h>
27
 
28
#include "csr1212.h"
29
#include "ieee1394_types.h"
30
#include "hosts.h"
31
#include "ieee1394.h"
32
#include "highlevel.h"
33
#include "ieee1394_core.h"
34
 
35
/* Module Parameters */
36
/* this module parameter can be used to disable mapping of the FCP registers */
37
 
38
static int fcp = 1;
39
module_param(fcp, int, 0444);
40
MODULE_PARM_DESC(fcp, "Map FCP registers (default = 1, disable = 0).");
41
 
42
static struct csr1212_keyval *node_cap = NULL;
43
 
44
static void add_host(struct hpsb_host *host);
45
static void remove_host(struct hpsb_host *host);
46
static void host_reset(struct hpsb_host *host);
47
static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
48
                     u64 addr, size_t length, u16 fl);
49
static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
50
                     quadlet_t *data, u64 addr, size_t length, u16 flags);
51
static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf,
52
                     u64 addr, size_t length, u16 flags);
53
static int write_regs(struct hpsb_host *host, int nodeid, int destid,
54
                      quadlet_t *data, u64 addr, size_t length, u16 flags);
55
static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
56
                     u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 fl);
57
static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store,
58
                       u64 addr, octlet_t data, octlet_t arg, int extcode, u16 fl);
59
static int read_config_rom(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
60
                           u64 addr, size_t length, u16 fl);
61
static u64 allocate_addr_range(u64 size, u32 alignment, void *__host);
62
static void release_addr_range(u64 addr, void *__host);
63
 
64
static struct hpsb_highlevel csr_highlevel = {
65
        .name =         "standard registers",
66
        .add_host =     add_host,
67
        .remove_host =  remove_host,
68
        .host_reset =   host_reset,
69
};
70
 
71
static struct hpsb_address_ops map_ops = {
72
        .read = read_maps,
73
};
74
 
75
static struct hpsb_address_ops fcp_ops = {
76
        .write = write_fcp,
77
};
78
 
79
static struct hpsb_address_ops reg_ops = {
80
        .read = read_regs,
81
        .write = write_regs,
82
        .lock = lock_regs,
83
        .lock64 = lock64_regs,
84
};
85
 
86
static struct hpsb_address_ops config_rom_ops = {
87
        .read = read_config_rom,
88
};
89
 
90
struct csr1212_bus_ops csr_bus_ops = {
91
        .allocate_addr_range =  allocate_addr_range,
92
        .release_addr =         release_addr_range,
93
};
94
 
95
 
96
static u16 csr_crc16(unsigned *data, int length)
97
{
98
        int check=0, i;
99
        int shift, sum, next=0;
100
 
101
        for (i = length; i; i--) {
102
                for (next = check, shift = 28; shift >= 0; shift -= 4 ) {
103
                        sum = ((next >> 12) ^ (be32_to_cpu(*data) >> shift)) & 0xf;
104
                        next = (next << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
105
                }
106
                check = next & 0xffff;
107
                data++;
108
        }
109
 
110
        return check;
111
}
112
 
113
static void host_reset(struct hpsb_host *host)
114
{
115
        host->csr.state &= 0x300;
116
 
117
        host->csr.bus_manager_id = 0x3f;
118
        host->csr.bandwidth_available = 4915;
119
        host->csr.channels_available_hi = 0xfffffffe;   /* pre-alloc ch 31 per 1394a-2000 */
120
        host->csr.channels_available_lo = ~0;
121
        host->csr.broadcast_channel = 0x80000000 | 31;
122
 
123
        if (host->is_irm) {
124
                if (host->driver->hw_csr_reg) {
125
                        host->driver->hw_csr_reg(host, 2, 0xfffffffe, ~0);
126
                }
127
        }
128
 
129
        host->csr.node_ids = host->node_id << 16;
130
 
131
        if (!host->is_root) {
132
                /* clear cmstr bit */
133
                host->csr.state &= ~0x100;
134
        }
135
 
136
        host->csr.topology_map[1] =
137
                cpu_to_be32(be32_to_cpu(host->csr.topology_map[1]) + 1);
138
        host->csr.topology_map[2] = cpu_to_be32(host->node_count << 16
139
                                                | host->selfid_count);
140
        host->csr.topology_map[0] =
141
                cpu_to_be32((host->selfid_count + 2) << 16
142
                            | csr_crc16(host->csr.topology_map + 1,
143
                                        host->selfid_count + 2));
144
 
145
        host->csr.speed_map[1] =
146
                cpu_to_be32(be32_to_cpu(host->csr.speed_map[1]) + 1);
147
        host->csr.speed_map[0] = cpu_to_be32(0x3f1 << 16
148
                                             | csr_crc16(host->csr.speed_map+1,
149
                                                         0x3f1));
150
}
151
 
152
/*
153
 * HI == seconds (bits 0:2)
154
 * LO == fractions of a second in units of 125usec (bits 19:31)
155
 *
156
 * Convert SPLIT_TIMEOUT to jiffies.
157
 * The default and minimum as per 1394a-2000 clause 8.3.2.2.6 is 100ms.
158
 */
159
static inline void calculate_expire(struct csr_control *csr)
160
{
161
        unsigned int usecs = (csr->split_timeout_hi & 7) * 1000000 +
162
                             (csr->split_timeout_lo >> 19) * 125;
163
 
164
        csr->expire = usecs_to_jiffies(usecs > 100000 ? usecs : 100000);
165
        HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
166
}
167
 
168
 
169
static void add_host(struct hpsb_host *host)
170
{
171
        struct csr1212_keyval *root;
172
        quadlet_t bus_info[CSR_BUS_INFO_SIZE];
173
 
174
        hpsb_register_addrspace(&csr_highlevel, host, &reg_ops,
175
                                CSR_REGISTER_BASE,
176
                                CSR_REGISTER_BASE + CSR_CONFIG_ROM);
177
        hpsb_register_addrspace(&csr_highlevel, host, &config_rom_ops,
178
                                CSR_REGISTER_BASE + CSR_CONFIG_ROM,
179
                                CSR_REGISTER_BASE + CSR_CONFIG_ROM_END);
180
        if (fcp) {
181
                hpsb_register_addrspace(&csr_highlevel, host, &fcp_ops,
182
                                        CSR_REGISTER_BASE + CSR_FCP_COMMAND,
183
                                        CSR_REGISTER_BASE + CSR_FCP_END);
184
        }
185
        hpsb_register_addrspace(&csr_highlevel, host, &map_ops,
186
                                CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP,
187
                                CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP_END);
188
        hpsb_register_addrspace(&csr_highlevel, host, &map_ops,
189
                                CSR_REGISTER_BASE + CSR_SPEED_MAP,
190
                                CSR_REGISTER_BASE + CSR_SPEED_MAP_END);
191
 
192
        spin_lock_init(&host->csr.lock);
193
 
194
        host->csr.state                 = 0;
195
        host->csr.node_ids              = 0;
196
        host->csr.split_timeout_hi      = 0;
197
        host->csr.split_timeout_lo      = 800 << 19;
198
        calculate_expire(&host->csr);
199
        host->csr.cycle_time            = 0;
200
        host->csr.bus_time              = 0;
201
        host->csr.bus_manager_id        = 0x3f;
202
        host->csr.bandwidth_available   = 4915;
203
        host->csr.channels_available_hi = 0xfffffffe;   /* pre-alloc ch 31 per 1394a-2000 */
204
        host->csr.channels_available_lo = ~0;
205
        host->csr.broadcast_channel = 0x80000000 | 31;
206
 
207
        if (host->is_irm) {
208
                if (host->driver->hw_csr_reg) {
209
                        host->driver->hw_csr_reg(host, 2, 0xfffffffe, ~0);
210
                }
211
        }
212
 
213
        if (host->csr.max_rec >= 9)
214
                host->csr.max_rom = 2;
215
        else if (host->csr.max_rec >= 5)
216
                host->csr.max_rom = 1;
217
        else
218
                host->csr.max_rom = 0;
219
 
220
        host->csr.generation = 2;
221
 
222
        bus_info[1] = __constant_cpu_to_be32(0x31333934);
223
        bus_info[2] = cpu_to_be32((hpsb_disable_irm ? 0 : 1 << CSR_IRMC_SHIFT) |
224
                                  (1 << CSR_CMC_SHIFT) |
225
                                  (1 << CSR_ISC_SHIFT) |
226
                                  (0 << CSR_BMC_SHIFT) |
227
                                  (0 << CSR_PMC_SHIFT) |
228
                                  (host->csr.cyc_clk_acc << CSR_CYC_CLK_ACC_SHIFT) |
229
                                  (host->csr.max_rec << CSR_MAX_REC_SHIFT) |
230
                                  (host->csr.max_rom << CSR_MAX_ROM_SHIFT) |
231
                                  (host->csr.generation << CSR_GENERATION_SHIFT) |
232
                                  host->csr.lnk_spd);
233
 
234
        bus_info[3] = cpu_to_be32(host->csr.guid_hi);
235
        bus_info[4] = cpu_to_be32(host->csr.guid_lo);
236
 
237
        /* The hardware copy of the bus info block will be set later when a
238
         * bus reset is issued. */
239
 
240
        csr1212_init_local_csr(host->csr.rom, bus_info, host->csr.max_rom);
241
 
242
        root = host->csr.rom->root_kv;
243
 
244
        if(csr1212_attach_keyval_to_directory(root, node_cap) != CSR1212_SUCCESS) {
245
                HPSB_ERR("Failed to attach Node Capabilities to root directory");
246
        }
247
 
248
        host->update_config_rom = 1;
249
}
250
 
251
static void remove_host(struct hpsb_host *host)
252
{
253
        quadlet_t bus_info[CSR_BUS_INFO_SIZE];
254
 
255
        bus_info[1] = __constant_cpu_to_be32(0x31333934);
256
        bus_info[2] = cpu_to_be32((0 << CSR_IRMC_SHIFT) |
257
                                  (0 << CSR_CMC_SHIFT) |
258
                                  (0 << CSR_ISC_SHIFT) |
259
                                  (0 << CSR_BMC_SHIFT) |
260
                                  (0 << CSR_PMC_SHIFT) |
261
                                  (host->csr.cyc_clk_acc << CSR_CYC_CLK_ACC_SHIFT) |
262
                                  (host->csr.max_rec << CSR_MAX_REC_SHIFT) |
263
                                  (0 << CSR_MAX_ROM_SHIFT) |
264
                                  (0 << CSR_GENERATION_SHIFT) |
265
                                  host->csr.lnk_spd);
266
 
267
        bus_info[3] = cpu_to_be32(host->csr.guid_hi);
268
        bus_info[4] = cpu_to_be32(host->csr.guid_lo);
269
 
270
        csr1212_detach_keyval_from_directory(host->csr.rom->root_kv, node_cap);
271
 
272
        csr1212_init_local_csr(host->csr.rom, bus_info, 0);
273
        host->update_config_rom = 1;
274
}
275
 
276
 
277
int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom,
278
        size_t buffersize, unsigned char rom_version)
279
{
280
        unsigned long flags;
281
        int ret;
282
 
283
        HPSB_NOTICE("hpsb_update_config_rom() is deprecated");
284
 
285
        spin_lock_irqsave(&host->csr.lock, flags);
286
        if (rom_version != host->csr.generation)
287
                ret = -1;
288
        else if (buffersize > host->csr.rom->cache_head->size)
289
                ret = -2;
290
        else {
291
                /* Just overwrite the generated ConfigROM image with new data,
292
                 * it can be regenerated later. */
293
                memcpy(host->csr.rom->cache_head->data, new_rom, buffersize);
294
                host->csr.rom->cache_head->len = buffersize;
295
 
296
                if (host->driver->set_hw_config_rom)
297
                        host->driver->set_hw_config_rom(host, host->csr.rom->bus_info_data);
298
                /* Increment the generation number to keep some sort of sync
299
                 * with the newer ConfigROM manipulation method. */
300
                host->csr.generation++;
301
                if (host->csr.generation > 0xf || host->csr.generation < 2)
302
                        host->csr.generation = 2;
303
                ret=0;
304
        }
305
        spin_unlock_irqrestore(&host->csr.lock, flags);
306
        return ret;
307
}
308
 
309
 
310
/* Read topology / speed maps and configuration ROM */
311
static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
312
                     u64 addr, size_t length, u16 fl)
313
{
314
        unsigned long flags;
315
        int csraddr = addr - CSR_REGISTER_BASE;
316
        const char *src;
317
 
318
        spin_lock_irqsave(&host->csr.lock, flags);
319
 
320
        if (csraddr < CSR_SPEED_MAP) {
321
                src = ((char *)host->csr.topology_map) + csraddr
322
                        - CSR_TOPOLOGY_MAP;
323
        } else {
324
                src = ((char *)host->csr.speed_map) + csraddr - CSR_SPEED_MAP;
325
        }
326
 
327
        memcpy(buffer, src, length);
328
        spin_unlock_irqrestore(&host->csr.lock, flags);
329
        return RCODE_COMPLETE;
330
}
331
 
332
 
333
#define out if (--length == 0) break
334
 
335
static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf,
336
                     u64 addr, size_t length, u16 flags)
337
{
338
        int csraddr = addr - CSR_REGISTER_BASE;
339
        int oldcycle;
340
        quadlet_t ret;
341
 
342
        if ((csraddr | length) & 0x3)
343
                return RCODE_TYPE_ERROR;
344
 
345
        length /= 4;
346
 
347
        switch (csraddr) {
348
        case CSR_STATE_CLEAR:
349
                *(buf++) = cpu_to_be32(host->csr.state);
350
                out;
351
        case CSR_STATE_SET:
352
                *(buf++) = cpu_to_be32(host->csr.state);
353
                out;
354
        case CSR_NODE_IDS:
355
                *(buf++) = cpu_to_be32(host->csr.node_ids);
356
                out;
357
 
358
        case CSR_RESET_START:
359
                return RCODE_TYPE_ERROR;
360
 
361
                /* address gap - handled by default below */
362
 
363
        case CSR_SPLIT_TIMEOUT_HI:
364
                *(buf++) = cpu_to_be32(host->csr.split_timeout_hi);
365
                out;
366
        case CSR_SPLIT_TIMEOUT_LO:
367
                *(buf++) = cpu_to_be32(host->csr.split_timeout_lo);
368
                out;
369
 
370
                /* address gap */
371
                return RCODE_ADDRESS_ERROR;
372
 
373
        case CSR_CYCLE_TIME:
374
                oldcycle = host->csr.cycle_time;
375
                host->csr.cycle_time =
376
                        host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
377
 
378
                if (oldcycle > host->csr.cycle_time) {
379
                        /* cycle time wrapped around */
380
                        host->csr.bus_time += 1 << 7;
381
                }
382
                *(buf++) = cpu_to_be32(host->csr.cycle_time);
383
                out;
384
        case CSR_BUS_TIME:
385
                oldcycle = host->csr.cycle_time;
386
                host->csr.cycle_time =
387
                        host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
388
 
389
                if (oldcycle > host->csr.cycle_time) {
390
                        /* cycle time wrapped around */
391
                        host->csr.bus_time += (1 << 7);
392
                }
393
                *(buf++) = cpu_to_be32(host->csr.bus_time
394
                                       | (host->csr.cycle_time >> 25));
395
                out;
396
 
397
                /* address gap */
398
                return RCODE_ADDRESS_ERROR;
399
 
400
        case CSR_BUSY_TIMEOUT:
401
                /* not yet implemented */
402
                return RCODE_ADDRESS_ERROR;
403
 
404
        case CSR_BUS_MANAGER_ID:
405
                if (host->driver->hw_csr_reg)
406
                        ret = host->driver->hw_csr_reg(host, 0, 0, 0);
407
                else
408
                        ret = host->csr.bus_manager_id;
409
 
410
                *(buf++) = cpu_to_be32(ret);
411
                out;
412
        case CSR_BANDWIDTH_AVAILABLE:
413
                if (host->driver->hw_csr_reg)
414
                        ret = host->driver->hw_csr_reg(host, 1, 0, 0);
415
                else
416
                        ret = host->csr.bandwidth_available;
417
 
418
                *(buf++) = cpu_to_be32(ret);
419
                out;
420
        case CSR_CHANNELS_AVAILABLE_HI:
421
                if (host->driver->hw_csr_reg)
422
                        ret = host->driver->hw_csr_reg(host, 2, 0, 0);
423
                else
424
                        ret = host->csr.channels_available_hi;
425
 
426
                *(buf++) = cpu_to_be32(ret);
427
                out;
428
        case CSR_CHANNELS_AVAILABLE_LO:
429
                if (host->driver->hw_csr_reg)
430
                        ret = host->driver->hw_csr_reg(host, 3, 0, 0);
431
                else
432
                        ret = host->csr.channels_available_lo;
433
 
434
                *(buf++) = cpu_to_be32(ret);
435
                out;
436
 
437
        case CSR_BROADCAST_CHANNEL:
438
                *(buf++) = cpu_to_be32(host->csr.broadcast_channel);
439
                out;
440
 
441
                /* address gap to end - fall through to default */
442
        default:
443
                return RCODE_ADDRESS_ERROR;
444
        }
445
 
446
        return RCODE_COMPLETE;
447
}
448
 
449
static int write_regs(struct hpsb_host *host, int nodeid, int destid,
450
                      quadlet_t *data, u64 addr, size_t length, u16 flags)
451
{
452
        int csraddr = addr - CSR_REGISTER_BASE;
453
 
454
        if ((csraddr | length) & 0x3)
455
                return RCODE_TYPE_ERROR;
456
 
457
        length /= 4;
458
 
459
        switch (csraddr) {
460
        case CSR_STATE_CLEAR:
461
                /* FIXME FIXME FIXME */
462
                printk("doh, someone wants to mess with state clear\n");
463
                out;
464
        case CSR_STATE_SET:
465
                printk("doh, someone wants to mess with state set\n");
466
                out;
467
 
468
        case CSR_NODE_IDS:
469
                host->csr.node_ids &= NODE_MASK << 16;
470
                host->csr.node_ids |= be32_to_cpu(*(data++)) & (BUS_MASK << 16);
471
                host->node_id = host->csr.node_ids >> 16;
472
                host->driver->devctl(host, SET_BUS_ID, host->node_id >> 6);
473
                out;
474
 
475
        case CSR_RESET_START:
476
                /* FIXME - perform command reset */
477
                out;
478
 
479
                /* address gap */
480
                return RCODE_ADDRESS_ERROR;
481
 
482
        case CSR_SPLIT_TIMEOUT_HI:
483
                host->csr.split_timeout_hi =
484
                        be32_to_cpu(*(data++)) & 0x00000007;
485
                calculate_expire(&host->csr);
486
                out;
487
        case CSR_SPLIT_TIMEOUT_LO:
488
                host->csr.split_timeout_lo =
489
                        be32_to_cpu(*(data++)) & 0xfff80000;
490
                calculate_expire(&host->csr);
491
                out;
492
 
493
                /* address gap */
494
                return RCODE_ADDRESS_ERROR;
495
 
496
        case CSR_CYCLE_TIME:
497
                /* should only be set by cycle start packet, automatically */
498
                host->csr.cycle_time = be32_to_cpu(*data);
499
                host->driver->devctl(host, SET_CYCLE_COUNTER,
500
                                       be32_to_cpu(*(data++)));
501
                out;
502
        case CSR_BUS_TIME:
503
                host->csr.bus_time = be32_to_cpu(*(data++)) & 0xffffff80;
504
                out;
505
 
506
                /* address gap */
507
                return RCODE_ADDRESS_ERROR;
508
 
509
        case CSR_BUSY_TIMEOUT:
510
                /* not yet implemented */
511
                return RCODE_ADDRESS_ERROR;
512
 
513
        case CSR_BUS_MANAGER_ID:
514
        case CSR_BANDWIDTH_AVAILABLE:
515
        case CSR_CHANNELS_AVAILABLE_HI:
516
        case CSR_CHANNELS_AVAILABLE_LO:
517
                /* these are not writable, only lockable */
518
                return RCODE_TYPE_ERROR;
519
 
520
        case CSR_BROADCAST_CHANNEL:
521
                /* only the valid bit can be written */
522
                host->csr.broadcast_channel = (host->csr.broadcast_channel & ~0x40000000)
523
                        | (be32_to_cpu(*data) & 0x40000000);
524
                out;
525
 
526
                /* address gap to end - fall through */
527
        default:
528
                return RCODE_ADDRESS_ERROR;
529
        }
530
 
531
        return RCODE_COMPLETE;
532
}
533
 
534
#undef out
535
 
536
 
537
static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
538
                     u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 fl)
539
{
540
        int csraddr = addr - CSR_REGISTER_BASE;
541
        unsigned long flags;
542
        quadlet_t *regptr = NULL;
543
 
544
        if (csraddr & 0x3)
545
                return RCODE_TYPE_ERROR;
546
 
547
        if (csraddr < CSR_BUS_MANAGER_ID || csraddr > CSR_CHANNELS_AVAILABLE_LO
548
            || extcode != EXTCODE_COMPARE_SWAP)
549
                goto unsupported_lockreq;
550
 
551
        data = be32_to_cpu(data);
552
        arg = be32_to_cpu(arg);
553
 
554
        /* Is somebody releasing the broadcast_channel on us? */
555
        if (csraddr == CSR_CHANNELS_AVAILABLE_HI && (data & 0x1)) {
556
                /* Note: this is may not be the right way to handle
557
                 * the problem, so we should look into the proper way
558
                 * eventually. */
559
                HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
560
                          "broadcast channel 31.  Ignoring.",
561
                          NODE_BUS_ARGS(host, nodeid));
562
 
563
                data &= ~0x1;   /* keep broadcast channel allocated */
564
        }
565
 
566
        if (host->driver->hw_csr_reg) {
567
                quadlet_t old;
568
 
569
                old = host->driver->
570
                        hw_csr_reg(host, (csraddr - CSR_BUS_MANAGER_ID) >> 2,
571
                                   data, arg);
572
 
573
                *store = cpu_to_be32(old);
574
                return RCODE_COMPLETE;
575
        }
576
 
577
        spin_lock_irqsave(&host->csr.lock, flags);
578
 
579
        switch (csraddr) {
580
        case CSR_BUS_MANAGER_ID:
581
                regptr = &host->csr.bus_manager_id;
582
                *store = cpu_to_be32(*regptr);
583
                if (*regptr == arg)
584
                        *regptr = data;
585
                break;
586
 
587
        case CSR_BANDWIDTH_AVAILABLE:
588
        {
589
                quadlet_t bandwidth;
590
                quadlet_t old;
591
                quadlet_t new;
592
 
593
                regptr = &host->csr.bandwidth_available;
594
                old = *regptr;
595
 
596
                /* bandwidth available algorithm adapted from IEEE 1394a-2000 spec */
597
                if (arg > 0x1fff) {
598
                        *store = cpu_to_be32(old);      /* change nothing */
599
                        break;
600
                }
601
                data &= 0x1fff;
602
                if (arg >= data) {
603
                        /* allocate bandwidth */
604
                        bandwidth = arg - data;
605
                        if (old >= bandwidth) {
606
                                new = old - bandwidth;
607
                                *store = cpu_to_be32(arg);
608
                                *regptr = new;
609
                        } else {
610
                                *store = cpu_to_be32(old);
611
                        }
612
                } else {
613
                        /* deallocate bandwidth */
614
                        bandwidth = data - arg;
615
                        if (old + bandwidth < 0x2000) {
616
                                new = old + bandwidth;
617
                                *store = cpu_to_be32(arg);
618
                                *regptr = new;
619
                        } else {
620
                                *store = cpu_to_be32(old);
621
                        }
622
                }
623
                break;
624
        }
625
 
626
        case CSR_CHANNELS_AVAILABLE_HI:
627
        {
628
                /* Lock algorithm for CHANNELS_AVAILABLE as recommended by 1394a-2000 */
629
                quadlet_t affected_channels = arg ^ data;
630
 
631
                regptr = &host->csr.channels_available_hi;
632
 
633
                if ((arg & affected_channels) == (*regptr & affected_channels)) {
634
                        *regptr ^= affected_channels;
635
                        *store = cpu_to_be32(arg);
636
                } else {
637
                        *store = cpu_to_be32(*regptr);
638
                }
639
 
640
                break;
641
        }
642
 
643
        case CSR_CHANNELS_AVAILABLE_LO:
644
        {
645
                /* Lock algorithm for CHANNELS_AVAILABLE as recommended by 1394a-2000 */
646
                quadlet_t affected_channels = arg ^ data;
647
 
648
                regptr = &host->csr.channels_available_lo;
649
 
650
                if ((arg & affected_channels) == (*regptr & affected_channels)) {
651
                        *regptr ^= affected_channels;
652
                        *store = cpu_to_be32(arg);
653
                } else {
654
                        *store = cpu_to_be32(*regptr);
655
                }
656
                break;
657
        }
658
        }
659
 
660
        spin_unlock_irqrestore(&host->csr.lock, flags);
661
 
662
        return RCODE_COMPLETE;
663
 
664
 unsupported_lockreq:
665
        switch (csraddr) {
666
        case CSR_STATE_CLEAR:
667
        case CSR_STATE_SET:
668
        case CSR_RESET_START:
669
        case CSR_NODE_IDS:
670
        case CSR_SPLIT_TIMEOUT_HI:
671
        case CSR_SPLIT_TIMEOUT_LO:
672
        case CSR_CYCLE_TIME:
673
        case CSR_BUS_TIME:
674
        case CSR_BROADCAST_CHANNEL:
675
                return RCODE_TYPE_ERROR;
676
 
677
        case CSR_BUSY_TIMEOUT:
678
                /* not yet implemented - fall through */
679
        default:
680
                return RCODE_ADDRESS_ERROR;
681
        }
682
}
683
 
684
static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store,
685
                       u64 addr, octlet_t data, octlet_t arg, int extcode, u16 fl)
686
{
687
        int csraddr = addr - CSR_REGISTER_BASE;
688
        unsigned long flags;
689
 
690
        data = be64_to_cpu(data);
691
        arg = be64_to_cpu(arg);
692
 
693
        if (csraddr & 0x3)
694
                return RCODE_TYPE_ERROR;
695
 
696
        if (csraddr != CSR_CHANNELS_AVAILABLE
697
            || extcode != EXTCODE_COMPARE_SWAP)
698
                goto unsupported_lock64req;
699
 
700
        /* Is somebody releasing the broadcast_channel on us? */
701
        if (csraddr == CSR_CHANNELS_AVAILABLE_HI && (data & 0x100000000ULL)) {
702
                /* Note: this is may not be the right way to handle
703
                 * the problem, so we should look into the proper way
704
                 * eventually. */
705
                HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
706
                          "broadcast channel 31.  Ignoring.",
707
                          NODE_BUS_ARGS(host, nodeid));
708
 
709
                data &= ~0x100000000ULL;        /* keep broadcast channel allocated */
710
        }
711
 
712
        if (host->driver->hw_csr_reg) {
713
                quadlet_t data_hi, data_lo;
714
                quadlet_t arg_hi, arg_lo;
715
                quadlet_t old_hi, old_lo;
716
 
717
                data_hi = data >> 32;
718
                data_lo = data & 0xFFFFFFFF;
719
                arg_hi = arg >> 32;
720
                arg_lo = arg & 0xFFFFFFFF;
721
 
722
                old_hi = host->driver->hw_csr_reg(host, (csraddr - CSR_BUS_MANAGER_ID) >> 2,
723
                                                  data_hi, arg_hi);
724
 
725
                old_lo = host->driver->hw_csr_reg(host, ((csraddr + 4) - CSR_BUS_MANAGER_ID) >> 2,
726
                                                  data_lo, arg_lo);
727
 
728
                *store = cpu_to_be64(((octlet_t)old_hi << 32) | old_lo);
729
        } else {
730
                octlet_t old;
731
                octlet_t affected_channels = arg ^ data;
732
 
733
                spin_lock_irqsave(&host->csr.lock, flags);
734
 
735
                old = ((octlet_t)host->csr.channels_available_hi << 32) | host->csr.channels_available_lo;
736
 
737
                if ((arg & affected_channels) == (old & affected_channels)) {
738
                        host->csr.channels_available_hi ^= (affected_channels >> 32);
739
                        host->csr.channels_available_lo ^= (affected_channels & 0xffffffff);
740
                        *store = cpu_to_be64(arg);
741
                } else {
742
                        *store = cpu_to_be64(old);
743
                }
744
 
745
                spin_unlock_irqrestore(&host->csr.lock, flags);
746
        }
747
 
748
        /* Is somebody erroneously releasing the broadcast_channel on us? */
749
        if (host->csr.channels_available_hi & 0x1)
750
                host->csr.channels_available_hi &= ~0x1;
751
 
752
        return RCODE_COMPLETE;
753
 
754
 unsupported_lock64req:
755
        switch (csraddr) {
756
        case CSR_STATE_CLEAR:
757
        case CSR_STATE_SET:
758
        case CSR_RESET_START:
759
        case CSR_NODE_IDS:
760
        case CSR_SPLIT_TIMEOUT_HI:
761
        case CSR_SPLIT_TIMEOUT_LO:
762
        case CSR_CYCLE_TIME:
763
        case CSR_BUS_TIME:
764
        case CSR_BUS_MANAGER_ID:
765
        case CSR_BROADCAST_CHANNEL:
766
        case CSR_BUSY_TIMEOUT:
767
        case CSR_BANDWIDTH_AVAILABLE:
768
                return RCODE_TYPE_ERROR;
769
 
770
        default:
771
                return RCODE_ADDRESS_ERROR;
772
        }
773
}
774
 
775
static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
776
                     quadlet_t *data, u64 addr, size_t length, u16 flags)
777
{
778
        int csraddr = addr - CSR_REGISTER_BASE;
779
 
780
        if (length > 512)
781
                return RCODE_TYPE_ERROR;
782
 
783
        switch (csraddr) {
784
        case CSR_FCP_COMMAND:
785
                highlevel_fcp_request(host, nodeid, 0, (u8 *)data, length);
786
                break;
787
        case CSR_FCP_RESPONSE:
788
                highlevel_fcp_request(host, nodeid, 1, (u8 *)data, length);
789
                break;
790
        default:
791
                return RCODE_TYPE_ERROR;
792
        }
793
 
794
        return RCODE_COMPLETE;
795
}
796
 
797
static int read_config_rom(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
798
                           u64 addr, size_t length, u16 fl)
799
{
800
        u32 offset = addr - CSR1212_REGISTER_SPACE_BASE;
801
 
802
        if (csr1212_read(host->csr.rom, offset, buffer, length) == CSR1212_SUCCESS)
803
                return RCODE_COMPLETE;
804
        else
805
                return RCODE_ADDRESS_ERROR;
806
}
807
 
808
static u64 allocate_addr_range(u64 size, u32 alignment, void *__host)
809
{
810
        struct hpsb_host *host = (struct hpsb_host*)__host;
811
 
812
        return hpsb_allocate_and_register_addrspace(&csr_highlevel,
813
                                                    host,
814
                                                    &config_rom_ops,
815
                                                    size, alignment,
816
                                                    CSR1212_UNITS_SPACE_BASE,
817
                                                    CSR1212_UNITS_SPACE_END);
818
}
819
 
820
static void release_addr_range(u64 addr, void *__host)
821
{
822
        struct hpsb_host *host = (struct hpsb_host*)__host;
823
        hpsb_unregister_addrspace(&csr_highlevel, host, addr);
824
}
825
 
826
 
827
int init_csr(void)
828
{
829
        node_cap = csr1212_new_immediate(CSR1212_KV_ID_NODE_CAPABILITIES, 0x0083c0);
830
        if (!node_cap) {
831
                HPSB_ERR("Failed to allocate memory for Node Capabilties ConfigROM entry!");
832
                return -ENOMEM;
833
        }
834
 
835
        hpsb_register_highlevel(&csr_highlevel);
836
 
837
        return 0;
838
}
839
 
840
void cleanup_csr(void)
841
{
842
        if (node_cap)
843
                csr1212_release_keyval(node_cap);
844
        hpsb_unregister_highlevel(&csr_highlevel);
845
}

powered by: WebSVN 2.1.0

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