aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2007-05-07 20:33:31 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2007-05-10 12:24:13 -0400
commite175569c4639872b5cf242c9d4a71cc40c5f3c29 (patch)
treec962499ff5db9cc91d7b618524221563f2ccf452
parent3e7cbae7c6dda18d427335b3ad98f1a0d40ef30c (diff)
firewire: Use lib/ implementation of CRC ITU-T.
With the CRC ITU-T implementation available in lib/ we can use that instead. This also fixes a bug in the topology map crc computation. Signed-off-by: Kristian Hoegsberg <krh@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (fixed Kconfig)
-rw-r--r--drivers/firewire/Kconfig1
-rw-r--r--drivers/firewire/fw-card.c35
-rw-r--r--drivers/firewire/fw-topology.c5
-rw-r--r--drivers/firewire/fw-topology.h5
4 files changed, 18 insertions, 28 deletions
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index 5fc56fac9700..5932c72f9e42 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -6,6 +6,7 @@ comment "An alternative FireWire stack is available with EXPERIMENTAL=y"
6config FIREWIRE 6config FIREWIRE
7 tristate "IEEE 1394 (FireWire) support (JUJU alternative stack, experimental)" 7 tristate "IEEE 1394 (FireWire) support (JUJU alternative stack, experimental)"
8 depends on EXPERIMENTAL 8 depends on EXPERIMENTAL
9 select CRC_ITU_T
9 help 10 help
10 IEEE 1394 describes a high performance serial bus, which is also 11 IEEE 1394 describes a high performance serial bus, which is also
11 known as FireWire(tm) or i.Link(tm) and is used for connecting all 12 known as FireWire(tm) or i.Link(tm) and is used for connecting all
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index a2de680d9d52..216965615ee8 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -23,31 +23,22 @@
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/rwsem.h> 25#include <linux/rwsem.h>
26#include <linux/crc-itu-t.h>
26#include "fw-transaction.h" 27#include "fw-transaction.h"
27#include "fw-topology.h" 28#include "fw-topology.h"
28#include "fw-device.h" 29#include "fw-device.h"
29 30
30/* The lib/crc16.c implementation uses the standard (0x8005) 31int fw_compute_block_crc(u32 *block)
31 * polynomial, but we need the ITU-T (or CCITT) polynomial (0x1021).
32 * The implementation below works on an array of host-endian u32
33 * words, assuming they'll be transmited msb first. */
34u16
35crc16_itu_t(const u32 *buffer, size_t length)
36{ 32{
37 int shift, i; 33 __be32 be32_block[256];
38 u32 data; 34 int i, length;
39 u16 sum, crc = 0;
40
41 for (i = 0; i < length; i++) {
42 data = *buffer++;
43 for (shift = 28; shift >= 0; shift -= 4 ) {
44 sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
45 crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
46 }
47 crc &= 0xffff;
48 }
49 35
50 return crc; 36 length = (*block >> 16) & 0xff;
37 for (i = 0; i < length; i++)
38 be32_block[i] = cpu_to_be32(block[i + 1]);
39 *block |= crc_itu_t(0, (u8 *) be32_block, length * 4);
40
41 return length;
51} 42}
52 43
53static DECLARE_RWSEM(card_rwsem); 44static DECLARE_RWSEM(card_rwsem);
@@ -126,10 +117,8 @@ generate_config_rom (struct fw_card *card, size_t *config_rom_length)
126 * assumes that CRC length and info length are identical for 117 * assumes that CRC length and info length are identical for
127 * the bus info block, which is always the case for this 118 * the bus info block, which is always the case for this
128 * implementation. */ 119 * implementation. */
129 for (i = 0; i < j; i += length + 1) { 120 for (i = 0; i < j; i += length + 1)
130 length = (config_rom[i] >> 16) & 0xff; 121 length = fw_compute_block_crc(config_rom + i);
131 config_rom[i] |= crc16_itu_t(&config_rom[i + 1], length);
132 }
133 122
134 *config_rom_length = j; 123 *config_rom_length = j;
135 124
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index bc8a3487c83a..018c6b8afba6 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -465,14 +465,13 @@ static void
465update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count) 465update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count)
466{ 466{
467 int node_count; 467 int node_count;
468 u32 crc;
469 468
470 card->topology_map[1]++; 469 card->topology_map[1]++;
471 node_count = (card->root_node->node_id & 0x3f) + 1; 470 node_count = (card->root_node->node_id & 0x3f) + 1;
472 card->topology_map[2] = (node_count << 16) | self_id_count; 471 card->topology_map[2] = (node_count << 16) | self_id_count;
473 crc = crc16_itu_t(card->topology_map + 1, self_id_count + 2); 472 card->topology_map[0] = (self_id_count + 2) << 16;
474 card->topology_map[0] = ((self_id_count + 2) << 16) | crc;
475 memcpy(&card->topology_map[3], self_ids, self_id_count * 4); 473 memcpy(&card->topology_map[3], self_ids, self_id_count * 4);
474 fw_compute_block_crc(card->topology_map);
476} 475}
477 476
478void 477void
diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h
index 913bfe160882..0778077e9d80 100644
--- a/drivers/firewire/fw-topology.h
+++ b/drivers/firewire/fw-topology.h
@@ -88,7 +88,8 @@ fw_node_put(struct fw_node *node)
88void 88void
89fw_destroy_nodes(struct fw_card *card); 89fw_destroy_nodes(struct fw_card *card);
90 90
91u16 91int
92crc16_itu_t(const u32 *buffer, size_t length); 92fw_compute_block_crc(u32 *block);
93
93 94
94#endif /* __fw_topology_h */ 95#endif /* __fw_topology_h */