4 * CSR implementation, iso/bus manager implementation.
6 * Copyright (C) 1999 Andreas E. Bombe
8 * This code is licensed under the GPL. See the file COPYING in the root
9 * directory of the kernel sources for details.
12 #include <linux/string.h>
14 #include "ieee1394_types.h"
17 #include "highlevel.h"
20 /* FIXME: this one won't work on little endian with big endian data */
21 static u16
csr_crc16(unsigned *data
, int length
)
24 int shift
, sum
, next
=0;
26 for (i
= length
; i
; i
--) {
27 for (next
= check
, shift
= 28; shift
>= 0; shift
-= 4 ) {
28 sum
= ((next
>> 12) ^ (*data
>> shift
)) & 0xf;
29 next
= (next
<< 4) ^ (sum
<< 12) ^ (sum
<< 5) ^ (sum
);
31 check
= next
& 0xffff;
38 static void host_reset(struct hpsb_host
*host
)
40 host
->csr
.state
&= 0x300;
42 host
->csr
.bus_manager_id
= 0x3f;
43 host
->csr
.bandwidth_available
= 4915;
44 host
->csr
.channels_available_hi
= ~0;
45 host
->csr
.channels_available_lo
= ~0;
47 host
->csr
.node_ids
= host
->node_id
<< 16;
51 host
->csr
.state
&= ~0x100;
54 host
->csr
.topology_map
[1] =
55 cpu_to_be32(be32_to_cpu(host
->csr
.topology_map
[1]) + 1);
56 host
->csr
.topology_map
[2] = cpu_to_be32(host
->node_count
<< 16
57 | host
->selfid_count
);
58 host
->csr
.topology_map
[0] =
59 cpu_to_be32((host
->selfid_count
+ 2) << 16
60 | csr_crc16(host
->csr
.topology_map
+ 1,
61 host
->selfid_count
+ 2));
63 host
->csr
.speed_map
[0] = cpu_to_be32(0x3f1 << 16
64 | csr_crc16(host
->csr
.speed_map
+1,
69 static void add_host(struct hpsb_host
*host
)
71 host
->csr
.lock
= SPIN_LOCK_UNLOCKED
;
73 host
->csr
.rom_size
= host
->template->get_rom(host
, &host
->csr
.rom
);
76 host
->csr
.node_ids
= 0;
77 host
->csr
.split_timeout_hi
= 0;
78 host
->csr
.split_timeout_lo
= 800 << 19;
79 host
->csr
.cycle_time
= 0;
80 host
->csr
.bus_time
= 0;
81 host
->csr
.bus_manager_id
= 0x3f;
82 host
->csr
.bandwidth_available
= 4915;
83 host
->csr
.channels_available_hi
= ~0;
84 host
->csr
.channels_available_lo
= ~0;
88 /* Read topology / speed maps and configuration ROM */
89 static int read_maps(struct hpsb_host
*host
, int nodeid
, quadlet_t
*buffer
,
90 u64 addr
, unsigned int length
)
92 int csraddr
= addr
- CSR_REGISTER_BASE
;
95 if (csraddr
< CSR_TOPOLOGY_MAP
) {
96 if (csraddr
+ length
> CSR_CONFIG_ROM
+ host
->csr
.rom_size
) {
97 return RCODE_ADDRESS_ERROR
;
99 src
= ((char *)host
->csr
.rom
) + csraddr
- CSR_CONFIG_ROM
;
100 } else if (csraddr
< CSR_SPEED_MAP
) {
101 src
= ((char *)host
->csr
.topology_map
) + csraddr
104 src
= ((char *)host
->csr
.speed_map
) + csraddr
- CSR_SPEED_MAP
;
107 memcpy(buffer
, src
, length
);
108 return RCODE_COMPLETE
;
112 #define out if (--length == 0) break
114 static int read_regs(struct hpsb_host
*host
, int nodeid
, quadlet_t
*buf
,
115 u64 addr
, unsigned int length
)
117 int csraddr
= addr
- CSR_REGISTER_BASE
;
120 if ((csraddr
| length
) & 0x3) {
121 return RCODE_TYPE_ERROR
;
127 case CSR_STATE_CLEAR
:
128 *(buf
++) = cpu_to_be32(host
->csr
.state
);
131 *(buf
++) = cpu_to_be32(host
->csr
.state
);
134 *(buf
++) = cpu_to_be32(host
->csr
.node_ids
);
137 case CSR_RESET_START
:
138 return RCODE_TYPE_ERROR
;
140 /* address gap - handled by default below */
142 case CSR_SPLIT_TIMEOUT_HI
:
143 *(buf
++) = cpu_to_be32(host
->csr
.split_timeout_hi
);
145 case CSR_SPLIT_TIMEOUT_LO
:
146 *(buf
++) = cpu_to_be32(host
->csr
.split_timeout_lo
);
150 return RCODE_ADDRESS_ERROR
;
153 oldcycle
= host
->csr
.cycle_time
;
154 host
->csr
.cycle_time
=
155 host
->template->devctl(host
, GET_CYCLE_COUNTER
, 0);
157 if (oldcycle
> host
->csr
.cycle_time
) {
158 /* cycle time wrapped around */
159 host
->csr
.bus_time
+= 1 << 7;
161 *(buf
++) = cpu_to_be32(host
->csr
.cycle_time
);
164 oldcycle
= host
->csr
.cycle_time
;
165 host
->csr
.cycle_time
=
166 host
->template->devctl(host
, GET_CYCLE_COUNTER
, 0);
168 if (oldcycle
> host
->csr
.cycle_time
) {
169 /* cycle time wrapped around */
170 host
->csr
.bus_time
+= (1 << 7);
172 *(buf
++) = cpu_to_be32(host
->csr
.bus_time
173 | (host
->csr
.cycle_time
>> 25));
177 return RCODE_ADDRESS_ERROR
;
179 case CSR_BUSY_TIMEOUT
:
180 /* not yet implemented */
181 return RCODE_ADDRESS_ERROR
;
183 case CSR_BUS_MANAGER_ID
:
184 *(buf
++) = cpu_to_be32(host
->csr
.bus_manager_id
);
186 case CSR_BANDWIDTH_AVAILABLE
:
187 *(buf
++) = cpu_to_be32(host
->csr
.bandwidth_available
);
189 case CSR_CHANNELS_AVAILABLE_HI
:
190 *(buf
++) = cpu_to_be32(host
->csr
.channels_available_hi
);
192 case CSR_CHANNELS_AVAILABLE_LO
:
193 *(buf
++) = cpu_to_be32(host
->csr
.channels_available_lo
);
196 /* address gap to end - fall through to default */
198 return RCODE_ADDRESS_ERROR
;
201 return RCODE_COMPLETE
;
204 static int write_regs(struct hpsb_host
*host
, int nodeid
, quadlet_t
*data
,
205 u64 addr
, unsigned int length
)
207 int csraddr
= addr
- CSR_REGISTER_BASE
;
209 if ((csraddr
| length
) & 0x3) {
210 return RCODE_TYPE_ERROR
;
216 case CSR_STATE_CLEAR
:
217 /* FIXME FIXME FIXME */
218 printk("doh, someone wants to mess with state clear\n");
221 printk("doh, someone wants to mess with state set\n");
225 host
->csr
.node_ids
&= NODE_MASK
<< 16;
226 host
->csr
.node_ids
|= be32_to_cpu(*(data
++)) & (BUS_MASK
<< 16);
227 host
->node_id
= host
->csr
.node_ids
>> 16;
228 host
->template->devctl(host
, SET_BUS_ID
, host
->node_id
>> 6);
231 case CSR_RESET_START
:
232 /* FIXME - perform command reset */
236 return RCODE_ADDRESS_ERROR
;
238 case CSR_SPLIT_TIMEOUT_HI
:
239 host
->csr
.split_timeout_hi
=
240 be32_to_cpu(*(data
++)) & 0x00000007;
242 case CSR_SPLIT_TIMEOUT_LO
:
243 host
->csr
.split_timeout_lo
=
244 be32_to_cpu(*(data
++)) & 0xfff80000;
248 return RCODE_ADDRESS_ERROR
;
251 /* should only be set by cycle start packet, automatically */
252 host
->csr
.cycle_time
= be32_to_cpu(*data
);
253 host
->template->devctl(host
, SET_CYCLE_COUNTER
,
254 be32_to_cpu(*(data
++)));
257 host
->csr
.bus_time
= be32_to_cpu(*(data
++)) & 0xffffff80;
261 return RCODE_ADDRESS_ERROR
;
263 case CSR_BUSY_TIMEOUT
:
264 /* not yet implemented */
265 return RCODE_ADDRESS_ERROR
;
267 case CSR_BUS_MANAGER_ID
:
268 case CSR_BANDWIDTH_AVAILABLE
:
269 case CSR_CHANNELS_AVAILABLE_HI
:
270 case CSR_CHANNELS_AVAILABLE_LO
:
271 /* these are not writable, only lockable */
272 return RCODE_TYPE_ERROR
;
274 /* address gap to end - fall through */
276 return RCODE_ADDRESS_ERROR
;
279 return RCODE_COMPLETE
;
285 /* helper function for lock_regs */
286 inline static void compare_swap(quadlet_t
*old
, quadlet_t data
, quadlet_t arg
)
288 if (*old
== be32_to_cpu(arg
)) {
289 *old
= be32_to_cpu(data
);
293 static int lock_regs(struct hpsb_host
*host
, int nodeid
, quadlet_t
*store
,
294 u64 addr
, quadlet_t data
, quadlet_t arg
, int extcode
)
296 int csraddr
= addr
- CSR_REGISTER_BASE
;
300 return RCODE_TYPE_ERROR
;
303 if ((csraddr
>= CSR_BUS_MANAGER_ID
)
304 && (csraddr
<= CSR_CHANNELS_AVAILABLE_LO
)) {
305 if (extcode
== EXTCODE_COMPARE_SWAP
) {
306 spin_lock_irqsave(&host
->csr
.lock
, flags
);
309 case CSR_BUS_MANAGER_ID
:
310 *store
= cpu_to_be32(host
->csr
.bus_manager_id
);
311 compare_swap(&host
->csr
.bus_manager_id
,
315 case CSR_BANDWIDTH_AVAILABLE
:
316 *store
= cpu_to_be32(host
->
317 csr
.bandwidth_available
);
318 compare_swap(&host
->csr
.bandwidth_available
,
322 case CSR_CHANNELS_AVAILABLE_HI
:
323 *store
= cpu_to_be32(host
->
324 csr
.channels_available_hi
);
325 compare_swap(&host
->csr
.channels_available_hi
,
329 case CSR_CHANNELS_AVAILABLE_LO
:
330 *store
= cpu_to_be32(host
->
331 csr
.channels_available_lo
);
332 compare_swap(&host
->csr
.channels_available_lo
,
337 spin_unlock_irqrestore(&host
->csr
.lock
, flags
);
338 return RCODE_COMPLETE
;
340 return RCODE_TYPE_ERROR
;
344 /* no locking for anything else yet */
346 case CSR_STATE_CLEAR
:
348 case CSR_RESET_START
:
350 case CSR_SPLIT_TIMEOUT_HI
:
351 case CSR_SPLIT_TIMEOUT_LO
:
354 return RCODE_TYPE_ERROR
;
356 case CSR_BUSY_TIMEOUT
:
357 /* not yet implemented - fall through */
359 return RCODE_ADDRESS_ERROR
;
363 static int write_fcp(struct hpsb_host
*host
, int nodeid
, quadlet_t
*data
,
364 u64 addr
, unsigned int length
)
366 int csraddr
= addr
- CSR_REGISTER_BASE
;
369 return RCODE_TYPE_ERROR
;
373 case CSR_FCP_COMMAND
:
374 highlevel_fcp_request(host
, nodeid
, 0, (u8
*)data
, length
);
376 case CSR_FCP_RESPONSE
:
377 highlevel_fcp_request(host
, nodeid
, 1, (u8
*)data
, length
);
380 return RCODE_TYPE_ERROR
;
383 return RCODE_COMPLETE
;
387 struct hpsb_highlevel_ops csr_ops
= {
389 host_reset
: host_reset
,
393 struct hpsb_address_ops map_ops
= {
397 struct hpsb_address_ops fcp_ops
= {
401 struct hpsb_address_ops reg_ops
= {
410 struct hpsb_highlevel
*hl
;
412 hl
= hpsb_register_highlevel("standard registers", &csr_ops
);
414 HPSB_ERR("out of memory during ieee1394 initialization");
418 hpsb_register_addrspace(hl
, ®_ops
, CSR_REGISTER_BASE
,
419 CSR_REGISTER_BASE
+ CSR_CONFIG_ROM
);
420 hpsb_register_addrspace(hl
, &map_ops
,
421 CSR_REGISTER_BASE
+ CSR_CONFIG_ROM
,
422 CSR_REGISTER_BASE
+ CSR_CONFIG_ROM_END
);
423 hpsb_register_addrspace(hl
, &fcp_ops
,
424 CSR_REGISTER_BASE
+ CSR_FCP_COMMAND
,
425 CSR_REGISTER_BASE
+ CSR_FCP_END
);
426 hpsb_register_addrspace(hl
, &map_ops
,
427 CSR_REGISTER_BASE
+ CSR_TOPOLOGY_MAP
,
428 CSR_REGISTER_BASE
+ CSR_TOPOLOGY_MAP_END
);
429 hpsb_register_addrspace(hl
, &map_ops
,
430 CSR_REGISTER_BASE
+ CSR_SPEED_MAP
,
431 CSR_REGISTER_BASE
+ CSR_SPEED_MAP_END
);