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, &reg_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