1 /*
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/string.h>
21 #include <linux/module.h> /* needed for MODULE_PARM */
22 #include <linux/param.h>
23 #include <linux/spinlock.h>
24
25 #include "ieee1394_types.h"
26 #include "hosts.h"
27 #include "ieee1394.h"
28 #include "highlevel.h"
29
30 /* Module Parameters */
31 /* this module parameter can be used to disable mapping of the FCP registers */
32 MODULE_PARM(fcp,"i");
33 MODULE_PARM_DESC(fcp, "FCP-registers");
34 static int fcp = 1;
35
csr_crc16(unsigned * data,int length)36 static u16 csr_crc16(unsigned *data, int length)
37 {
38 int check=0, i;
39 int shift, sum, next=0;
40
41 for (i = length; i; i--) {
42 for (next = check, shift = 28; shift >= 0; shift -= 4 ) {
43 sum = ((next >> 12) ^ (be32_to_cpu(*data) >> shift)) & 0xf;
44 next = (next << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
45 }
46 check = next & 0xffff;
47 data++;
48 }
49
50 return check;
51 }
52
host_reset(struct hpsb_host * host)53 static void host_reset(struct hpsb_host *host)
54 {
55 host->csr.state &= 0x300;
56
57 host->csr.bus_manager_id = 0x3f;
58 host->csr.bandwidth_available = 4915;
59 host->csr.channels_available_hi = 0xfffffffe; /* pre-alloc ch 31 per 1394a-2000 */
60 host->csr.channels_available_lo = ~0;
61 host->csr.broadcast_channel = 0x80000000 | 31;
62
63 if (host->is_irm) {
64 if (host->driver->hw_csr_reg) {
65 host->driver->hw_csr_reg(host, 2, 0xfffffffe, ~0);
66 }
67 }
68
69 host->csr.node_ids = host->node_id << 16;
70
71 if (!host->is_root) {
72 /* clear cmstr bit */
73 host->csr.state &= ~0x100;
74 }
75
76 host->csr.topology_map[1] =
77 cpu_to_be32(be32_to_cpu(host->csr.topology_map[1]) + 1);
78 host->csr.topology_map[2] = cpu_to_be32(host->node_count << 16
79 | host->selfid_count);
80 host->csr.topology_map[0] =
81 cpu_to_be32((host->selfid_count + 2) << 16
82 | csr_crc16(host->csr.topology_map + 1,
83 host->selfid_count + 2));
84
85 host->csr.speed_map[1] =
86 cpu_to_be32(be32_to_cpu(host->csr.speed_map[1]) + 1);
87 host->csr.speed_map[0] = cpu_to_be32(0x3f1 << 16
88 | csr_crc16(host->csr.speed_map+1,
89 0x3f1));
90 }
91
92 /*
93 * HI == seconds (bits 0:2)
94 * LO == fraction units of 1/8000 of a second, as per 1394 (bits 19:31)
95 *
96 * Convert to units and then to HZ, for comparison to jiffies.
97 *
98 * By default this will end up being 800 units, or 100ms (125usec per
99 * unit).
100 *
101 * NOTE: The spec says 1/8000, but also says we can compute based on 1/8192
102 * like CSR specifies. Should make our math less complex.
103 */
calculate_expire(struct csr_control * csr)104 static inline void calculate_expire(struct csr_control *csr)
105 {
106 unsigned long units;
107
108 /* Take the seconds, and convert to units */
109 units = (unsigned long)(csr->split_timeout_hi & 0x07) << 13;
110
111 /* Add in the fractional units */
112 units += (unsigned long)(csr->split_timeout_lo >> 19);
113
114 /* Convert to jiffies */
115 csr->expire = (unsigned long)(units * HZ) >> 13UL;
116
117 /* Just to keep from rounding low */
118 csr->expire++;
119
120 HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%d", csr->expire, HZ);
121 }
122
123
add_host(struct hpsb_host * host)124 static void add_host(struct hpsb_host *host)
125 {
126 host->csr.lock = SPIN_LOCK_UNLOCKED;
127
128 host->csr.rom_size = host->driver->get_rom(host, &host->csr.rom);
129 host->csr.rom_version = 0;
130 host->csr.state = 0;
131 host->csr.node_ids = 0;
132 host->csr.split_timeout_hi = 0;
133 host->csr.split_timeout_lo = 800 << 19;
134 calculate_expire(&host->csr);
135 host->csr.cycle_time = 0;
136 host->csr.bus_time = 0;
137 host->csr.bus_manager_id = 0x3f;
138 host->csr.bandwidth_available = 4915;
139 host->csr.channels_available_hi = 0xfffffffe; /* pre-alloc ch 31 per 1394a-2000 */
140 host->csr.channels_available_lo = ~0;
141 host->csr.broadcast_channel = 0x80000000 | 31;
142
143 if (host->is_irm) {
144 if (host->driver->hw_csr_reg) {
145 host->driver->hw_csr_reg(host, 2, 0xfffffffe, ~0);
146 }
147 }
148 }
149
hpsb_update_config_rom(struct hpsb_host * host,const quadlet_t * new_rom,size_t size,unsigned char rom_version)150 int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom,
151 size_t size, unsigned char rom_version)
152 {
153 unsigned long flags;
154 int ret;
155
156 spin_lock_irqsave(&host->csr.lock, flags);
157 if (rom_version != host->csr.rom_version)
158 ret = -1;
159 else if (size > (CSR_CONFIG_ROM_SIZE << 2))
160 ret = -2;
161 else {
162 memcpy(host->csr.rom,new_rom,size);
163 host->csr.rom_size=size;
164 host->csr.rom_version++;
165 ret=0;
166 }
167 spin_unlock_irqrestore(&host->csr.lock, flags);
168 return ret;
169 }
170
hpsb_get_config_rom(struct hpsb_host * host,quadlet_t * buffer,size_t buffersize,size_t * rom_size,unsigned char * rom_version)171 int hpsb_get_config_rom(struct hpsb_host *host, quadlet_t *buffer,
172 size_t buffersize, size_t *rom_size, unsigned char *rom_version)
173 {
174 unsigned long flags;
175 int ret;
176
177 spin_lock_irqsave(&host->csr.lock, flags);
178 *rom_version=host->csr.rom_version;
179 *rom_size=host->csr.rom_size;
180 if (buffersize < host->csr.rom_size)
181 ret = -1;
182 else {
183 memcpy(buffer,host->csr.rom,host->csr.rom_size);
184 ret=0;
185 }
186 spin_unlock_irqrestore(&host->csr.lock, flags);
187 return ret;
188 }
189
190
191 /* Read topology / speed maps and configuration ROM */
read_maps(struct hpsb_host * host,int nodeid,quadlet_t * buffer,u64 addr,size_t length,u16 fl)192 static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
193 u64 addr, size_t length, u16 fl)
194 {
195 unsigned long flags;
196 int csraddr = addr - CSR_REGISTER_BASE;
197 const char *src;
198
199 spin_lock_irqsave(&host->csr.lock, flags);
200
201 if (csraddr < CSR_TOPOLOGY_MAP) {
202 if (csraddr + length > CSR_CONFIG_ROM + host->csr.rom_size) {
203 spin_unlock_irqrestore(&host->csr.lock, flags);
204 return RCODE_ADDRESS_ERROR;
205 }
206 src = ((char *)host->csr.rom) + csraddr - CSR_CONFIG_ROM;
207 } else if (csraddr < CSR_SPEED_MAP) {
208 src = ((char *)host->csr.topology_map) + csraddr
209 - CSR_TOPOLOGY_MAP;
210 } else {
211 src = ((char *)host->csr.speed_map) + csraddr - CSR_SPEED_MAP;
212 }
213
214 memcpy(buffer, src, length);
215 spin_unlock_irqrestore(&host->csr.lock, flags);
216 return RCODE_COMPLETE;
217 }
218
219
220 #define out if (--length == 0) break
221
read_regs(struct hpsb_host * host,int nodeid,quadlet_t * buf,u64 addr,size_t length,u16 flags)222 static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf,
223 u64 addr, size_t length, u16 flags)
224 {
225 int csraddr = addr - CSR_REGISTER_BASE;
226 int oldcycle;
227 quadlet_t ret;
228
229 if ((csraddr | length) & 0x3)
230 return RCODE_TYPE_ERROR;
231
232 length /= 4;
233
234 switch (csraddr) {
235 case CSR_STATE_CLEAR:
236 *(buf++) = cpu_to_be32(host->csr.state);
237 out;
238 case CSR_STATE_SET:
239 *(buf++) = cpu_to_be32(host->csr.state);
240 out;
241 case CSR_NODE_IDS:
242 *(buf++) = cpu_to_be32(host->csr.node_ids);
243 out;
244
245 case CSR_RESET_START:
246 return RCODE_TYPE_ERROR;
247
248 /* address gap - handled by default below */
249
250 case CSR_SPLIT_TIMEOUT_HI:
251 *(buf++) = cpu_to_be32(host->csr.split_timeout_hi);
252 out;
253 case CSR_SPLIT_TIMEOUT_LO:
254 *(buf++) = cpu_to_be32(host->csr.split_timeout_lo);
255 out;
256
257 /* address gap */
258 return RCODE_ADDRESS_ERROR;
259
260 case CSR_CYCLE_TIME:
261 oldcycle = host->csr.cycle_time;
262 host->csr.cycle_time =
263 host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
264
265 if (oldcycle > host->csr.cycle_time) {
266 /* cycle time wrapped around */
267 host->csr.bus_time += 1 << 7;
268 }
269 *(buf++) = cpu_to_be32(host->csr.cycle_time);
270 out;
271 case CSR_BUS_TIME:
272 oldcycle = host->csr.cycle_time;
273 host->csr.cycle_time =
274 host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
275
276 if (oldcycle > host->csr.cycle_time) {
277 /* cycle time wrapped around */
278 host->csr.bus_time += (1 << 7);
279 }
280 *(buf++) = cpu_to_be32(host->csr.bus_time
281 | (host->csr.cycle_time >> 25));
282 out;
283
284 /* address gap */
285 return RCODE_ADDRESS_ERROR;
286
287 case CSR_BUSY_TIMEOUT:
288 /* not yet implemented */
289 return RCODE_ADDRESS_ERROR;
290
291 case CSR_BUS_MANAGER_ID:
292 if (host->driver->hw_csr_reg)
293 ret = host->driver->hw_csr_reg(host, 0, 0, 0);
294 else
295 ret = host->csr.bus_manager_id;
296
297 *(buf++) = cpu_to_be32(ret);
298 out;
299 case CSR_BANDWIDTH_AVAILABLE:
300 if (host->driver->hw_csr_reg)
301 ret = host->driver->hw_csr_reg(host, 1, 0, 0);
302 else
303 ret = host->csr.bandwidth_available;
304
305 *(buf++) = cpu_to_be32(ret);
306 out;
307 case CSR_CHANNELS_AVAILABLE_HI:
308 if (host->driver->hw_csr_reg)
309 ret = host->driver->hw_csr_reg(host, 2, 0, 0);
310 else
311 ret = host->csr.channels_available_hi;
312
313 *(buf++) = cpu_to_be32(ret);
314 out;
315 case CSR_CHANNELS_AVAILABLE_LO:
316 if (host->driver->hw_csr_reg)
317 ret = host->driver->hw_csr_reg(host, 3, 0, 0);
318 else
319 ret = host->csr.channels_available_lo;
320
321 *(buf++) = cpu_to_be32(ret);
322 out;
323
324 case CSR_BROADCAST_CHANNEL:
325 *(buf++) = cpu_to_be32(host->csr.broadcast_channel);
326 out;
327
328 /* address gap to end - fall through to default */
329 default:
330 return RCODE_ADDRESS_ERROR;
331 }
332
333 return RCODE_COMPLETE;
334 }
335
write_regs(struct hpsb_host * host,int nodeid,int destid,quadlet_t * data,u64 addr,size_t length,u16 flags)336 static int write_regs(struct hpsb_host *host, int nodeid, int destid,
337 quadlet_t *data, u64 addr, size_t length, u16 flags)
338 {
339 int csraddr = addr - CSR_REGISTER_BASE;
340
341 if ((csraddr | length) & 0x3)
342 return RCODE_TYPE_ERROR;
343
344 length /= 4;
345
346 switch (csraddr) {
347 case CSR_STATE_CLEAR:
348 /* FIXME FIXME FIXME */
349 printk("doh, someone wants to mess with state clear\n");
350 out;
351 case CSR_STATE_SET:
352 printk("doh, someone wants to mess with state set\n");
353 out;
354
355 case CSR_NODE_IDS:
356 host->csr.node_ids &= NODE_MASK << 16;
357 host->csr.node_ids |= be32_to_cpu(*(data++)) & (BUS_MASK << 16);
358 host->node_id = host->csr.node_ids >> 16;
359 host->driver->devctl(host, SET_BUS_ID, host->node_id >> 6);
360 out;
361
362 case CSR_RESET_START:
363 /* FIXME - perform command reset */
364 out;
365
366 /* address gap */
367 return RCODE_ADDRESS_ERROR;
368
369 case CSR_SPLIT_TIMEOUT_HI:
370 host->csr.split_timeout_hi =
371 be32_to_cpu(*(data++)) & 0x00000007;
372 calculate_expire(&host->csr);
373 out;
374 case CSR_SPLIT_TIMEOUT_LO:
375 host->csr.split_timeout_lo =
376 be32_to_cpu(*(data++)) & 0xfff80000;
377 calculate_expire(&host->csr);
378 out;
379
380 /* address gap */
381 return RCODE_ADDRESS_ERROR;
382
383 case CSR_CYCLE_TIME:
384 /* should only be set by cycle start packet, automatically */
385 host->csr.cycle_time = be32_to_cpu(*data);
386 host->driver->devctl(host, SET_CYCLE_COUNTER,
387 be32_to_cpu(*(data++)));
388 out;
389 case CSR_BUS_TIME:
390 host->csr.bus_time = be32_to_cpu(*(data++)) & 0xffffff80;
391 out;
392
393 /* address gap */
394 return RCODE_ADDRESS_ERROR;
395
396 case CSR_BUSY_TIMEOUT:
397 /* not yet implemented */
398 return RCODE_ADDRESS_ERROR;
399
400 case CSR_BUS_MANAGER_ID:
401 case CSR_BANDWIDTH_AVAILABLE:
402 case CSR_CHANNELS_AVAILABLE_HI:
403 case CSR_CHANNELS_AVAILABLE_LO:
404 /* these are not writable, only lockable */
405 return RCODE_TYPE_ERROR;
406
407 case CSR_BROADCAST_CHANNEL:
408 /* only the valid bit can be written */
409 host->csr.broadcast_channel = (host->csr.broadcast_channel & ~0x40000000)
410 | (be32_to_cpu(*data) & 0x40000000);
411 out;
412
413 /* address gap to end - fall through */
414 default:
415 return RCODE_ADDRESS_ERROR;
416 }
417
418 return RCODE_COMPLETE;
419 }
420
421 #undef out
422
423
lock_regs(struct hpsb_host * host,int nodeid,quadlet_t * store,u64 addr,quadlet_t data,quadlet_t arg,int extcode,u16 fl)424 static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
425 u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 fl)
426 {
427 int csraddr = addr - CSR_REGISTER_BASE;
428 unsigned long flags;
429 quadlet_t *regptr = NULL;
430
431 if (csraddr & 0x3)
432 return RCODE_TYPE_ERROR;
433
434 if (csraddr < CSR_BUS_MANAGER_ID || csraddr > CSR_CHANNELS_AVAILABLE_LO
435 || extcode != EXTCODE_COMPARE_SWAP)
436 goto unsupported_lockreq;
437
438 data = be32_to_cpu(data);
439 arg = be32_to_cpu(arg);
440
441 /* Is somebody releasing the broadcast_channel on us? */
442 if (csraddr == CSR_CHANNELS_AVAILABLE_HI && (data & 0x1)) {
443 /* Note: this is may not be the right way to handle
444 * the problem, so we should look into the proper way
445 * eventually. */
446 HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
447 "broadcast channel 31. Ignoring.",
448 NODE_BUS_ARGS(host, nodeid));
449
450 data &= ~0x1; /* keep broadcast channel allocated */
451 }
452
453 if (host->driver->hw_csr_reg) {
454 quadlet_t old;
455
456 old = host->driver->
457 hw_csr_reg(host, (csraddr - CSR_BUS_MANAGER_ID) >> 2,
458 data, arg);
459
460 *store = cpu_to_be32(old);
461 return RCODE_COMPLETE;
462 }
463
464 spin_lock_irqsave(&host->csr.lock, flags);
465
466 switch (csraddr) {
467 case CSR_BUS_MANAGER_ID:
468 regptr = &host->csr.bus_manager_id;
469 *store = cpu_to_be32(*regptr);
470 if (*regptr == arg)
471 *regptr = data;
472 break;
473
474 case CSR_BANDWIDTH_AVAILABLE:
475 {
476 quadlet_t bandwidth;
477 quadlet_t old;
478 quadlet_t new;
479
480 regptr = &host->csr.bandwidth_available;
481 old = *regptr;
482
483 /* bandwidth available algorithm adapted from IEEE 1394a-2000 spec */
484 if (arg > 0x1fff) {
485 *store = cpu_to_be32(old); /* change nothing */
486 break;
487 }
488 data &= 0x1fff;
489 if (arg >= data) {
490 /* allocate bandwidth */
491 bandwidth = arg - data;
492 if (old >= bandwidth) {
493 new = old - bandwidth;
494 *store = cpu_to_be32(arg);
495 *regptr = new;
496 } else {
497 *store = cpu_to_be32(old);
498 }
499 } else {
500 /* deallocate bandwidth */
501 bandwidth = data - arg;
502 if (old + bandwidth < 0x2000) {
503 new = old + bandwidth;
504 *store = cpu_to_be32(arg);
505 *regptr = new;
506 } else {
507 *store = cpu_to_be32(old);
508 }
509 }
510 break;
511 }
512
513 case CSR_CHANNELS_AVAILABLE_HI:
514 {
515 /* Lock algorithm for CHANNELS_AVAILABLE as recommended by 1394a-2000 */
516 quadlet_t affected_channels = arg ^ data;
517
518 regptr = &host->csr.channels_available_hi;
519
520 if ((arg & affected_channels) == (*regptr & affected_channels)) {
521 *regptr ^= affected_channels;
522 *store = cpu_to_be32(arg);
523 } else {
524 *store = cpu_to_be32(*regptr);
525 }
526
527 break;
528 }
529
530 case CSR_CHANNELS_AVAILABLE_LO:
531 {
532 /* Lock algorithm for CHANNELS_AVAILABLE as recommended by 1394a-2000 */
533 quadlet_t affected_channels = arg ^ data;
534
535 regptr = &host->csr.channels_available_lo;
536
537 if ((arg & affected_channels) == (*regptr & affected_channels)) {
538 *regptr ^= affected_channels;
539 *store = cpu_to_be32(arg);
540 } else {
541 *store = cpu_to_be32(*regptr);
542 }
543 break;
544 }
545 }
546
547 spin_unlock_irqrestore(&host->csr.lock, flags);
548
549 return RCODE_COMPLETE;
550
551 unsupported_lockreq:
552 switch (csraddr) {
553 case CSR_STATE_CLEAR:
554 case CSR_STATE_SET:
555 case CSR_RESET_START:
556 case CSR_NODE_IDS:
557 case CSR_SPLIT_TIMEOUT_HI:
558 case CSR_SPLIT_TIMEOUT_LO:
559 case CSR_CYCLE_TIME:
560 case CSR_BUS_TIME:
561 case CSR_BROADCAST_CHANNEL:
562 return RCODE_TYPE_ERROR;
563
564 case CSR_BUSY_TIMEOUT:
565 /* not yet implemented - fall through */
566 default:
567 return RCODE_ADDRESS_ERROR;
568 }
569 }
570
lock64_regs(struct hpsb_host * host,int nodeid,octlet_t * store,u64 addr,octlet_t data,octlet_t arg,int extcode,u16 fl)571 static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store,
572 u64 addr, octlet_t data, octlet_t arg, int extcode, u16 fl)
573 {
574 int csraddr = addr - CSR_REGISTER_BASE;
575 unsigned long flags;
576
577 data = be64_to_cpu(data);
578 arg = be64_to_cpu(arg);
579
580 if (csraddr & 0x3)
581 return RCODE_TYPE_ERROR;
582
583 if (csraddr != CSR_CHANNELS_AVAILABLE
584 || extcode != EXTCODE_COMPARE_SWAP)
585 goto unsupported_lock64req;
586
587 /* Is somebody releasing the broadcast_channel on us? */
588 if (csraddr == CSR_CHANNELS_AVAILABLE_HI && (data & 0x100000000ULL)) {
589 /* Note: this is may not be the right way to handle
590 * the problem, so we should look into the proper way
591 * eventually. */
592 HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
593 "broadcast channel 31. Ignoring.",
594 NODE_BUS_ARGS(host, nodeid));
595
596 data &= ~0x100000000ULL; /* keep broadcast channel allocated */
597 }
598
599 if (host->driver->hw_csr_reg) {
600 quadlet_t data_hi, data_lo;
601 quadlet_t arg_hi, arg_lo;
602 quadlet_t old_hi, old_lo;
603
604 data_hi = data >> 32;
605 data_lo = data & 0xFFFFFFFF;
606 arg_hi = arg >> 32;
607 arg_lo = arg & 0xFFFFFFFF;
608
609 old_hi = host->driver->hw_csr_reg(host, (csraddr - CSR_BUS_MANAGER_ID) >> 2,
610 data_hi, arg_hi);
611
612 old_lo = host->driver->hw_csr_reg(host, ((csraddr + 4) - CSR_BUS_MANAGER_ID) >> 2,
613 data_lo, arg_lo);
614
615 *store = cpu_to_be64(((octlet_t)old_hi << 32) | old_lo);
616 } else {
617 octlet_t old;
618 octlet_t affected_channels = arg ^ data;
619
620 spin_lock_irqsave(&host->csr.lock, flags);
621
622 old = ((octlet_t)host->csr.channels_available_hi << 32) | host->csr.channels_available_lo;
623
624 if ((arg & affected_channels) == (old & affected_channels)) {
625 host->csr.channels_available_hi ^= (affected_channels >> 32);
626 host->csr.channels_available_lo ^= (affected_channels & 0xffffffff);
627 *store = cpu_to_be64(arg);
628 } else {
629 *store = cpu_to_be64(old);
630 }
631
632 spin_unlock_irqrestore(&host->csr.lock, flags);
633 }
634
635 /* Is somebody erroneously releasing the broadcast_channel on us? */
636 if (host->csr.channels_available_hi & 0x1)
637 host->csr.channels_available_hi &= ~0x1;
638
639 return RCODE_COMPLETE;
640
641 unsupported_lock64req:
642 switch (csraddr) {
643 case CSR_STATE_CLEAR:
644 case CSR_STATE_SET:
645 case CSR_RESET_START:
646 case CSR_NODE_IDS:
647 case CSR_SPLIT_TIMEOUT_HI:
648 case CSR_SPLIT_TIMEOUT_LO:
649 case CSR_CYCLE_TIME:
650 case CSR_BUS_TIME:
651 case CSR_BUS_MANAGER_ID:
652 case CSR_BROADCAST_CHANNEL:
653 case CSR_BUSY_TIMEOUT:
654 case CSR_BANDWIDTH_AVAILABLE:
655 return RCODE_TYPE_ERROR;
656
657 default:
658 return RCODE_ADDRESS_ERROR;
659 }
660 }
661
write_fcp(struct hpsb_host * host,int nodeid,int dest,quadlet_t * data,u64 addr,size_t length,u16 flags)662 static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
663 quadlet_t *data, u64 addr, size_t length, u16 flags)
664 {
665 int csraddr = addr - CSR_REGISTER_BASE;
666
667 if (length > 512)
668 return RCODE_TYPE_ERROR;
669
670 switch (csraddr) {
671 case CSR_FCP_COMMAND:
672 highlevel_fcp_request(host, nodeid, 0, (u8 *)data, length);
673 break;
674 case CSR_FCP_RESPONSE:
675 highlevel_fcp_request(host, nodeid, 1, (u8 *)data, length);
676 break;
677 default:
678 return RCODE_TYPE_ERROR;
679 }
680
681 return RCODE_COMPLETE;
682 }
683
684
685 static struct hpsb_highlevel csr_highlevel = {
686 .name = "standard registers",
687 .add_host = add_host,
688 .host_reset = host_reset,
689 };
690
691
692 static struct hpsb_address_ops map_ops = {
693 .read = read_maps,
694 };
695
696 static struct hpsb_address_ops fcp_ops = {
697 .write = write_fcp,
698 };
699
700 static struct hpsb_address_ops reg_ops = {
701 .read = read_regs,
702 .write = write_regs,
703 .lock = lock_regs,
704 .lock64 = lock64_regs,
705 };
706
init_csr(void)707 void init_csr(void)
708 {
709 hpsb_register_highlevel(&csr_highlevel);
710
711 hpsb_register_addrspace(&csr_highlevel, ®_ops, CSR_REGISTER_BASE,
712 CSR_REGISTER_BASE + CSR_CONFIG_ROM);
713 hpsb_register_addrspace(&csr_highlevel, &map_ops,
714 CSR_REGISTER_BASE + CSR_CONFIG_ROM,
715 CSR_REGISTER_BASE + CSR_CONFIG_ROM_END);
716 if (fcp) {
717 hpsb_register_addrspace(&csr_highlevel, &fcp_ops,
718 CSR_REGISTER_BASE + CSR_FCP_COMMAND,
719 CSR_REGISTER_BASE + CSR_FCP_END);
720 }
721 hpsb_register_addrspace(&csr_highlevel, &map_ops,
722 CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP,
723 CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP_END);
724 hpsb_register_addrspace(&csr_highlevel, &map_ops,
725 CSR_REGISTER_BASE + CSR_SPEED_MAP,
726 CSR_REGISTER_BASE + CSR_SPEED_MAP_END);
727 }
728
cleanup_csr(void)729 void cleanup_csr(void)
730 {
731 hpsb_unregister_highlevel(&csr_highlevel);
732 }
733