diff options
author | Kristian Høgsberg <krh@redhat.com> | 2007-05-07 20:33:31 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2007-05-10 12:24:13 -0400 |
commit | e175569c4639872b5cf242c9d4a71cc40c5f3c29 (patch) | |
tree | c962499ff5db9cc91d7b618524221563f2ccf452 | |
parent | 3e7cbae7c6dda18d427335b3ad98f1a0d40ef30c (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/Kconfig | 1 | ||||
-rw-r--r-- | drivers/firewire/fw-card.c | 35 | ||||
-rw-r--r-- | drivers/firewire/fw-topology.c | 5 | ||||
-rw-r--r-- | drivers/firewire/fw-topology.h | 5 |
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" | |||
6 | config FIREWIRE | 6 | config 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) | 31 | int 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. */ | ||
34 | u16 | ||
35 | crc16_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 | ||
53 | static DECLARE_RWSEM(card_rwsem); | 44 | static 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 | |||
465 | update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count) | 465 | update_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 | ||
478 | void | 477 | void |
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) | |||
88 | void | 88 | void |
89 | fw_destroy_nodes(struct fw_card *card); | 89 | fw_destroy_nodes(struct fw_card *card); |
90 | 90 | ||
91 | u16 | 91 | int |
92 | crc16_itu_t(const u32 *buffer, size_t length); | 92 | fw_compute_block_crc(u32 *block); |
93 | |||
93 | 94 | ||
94 | #endif /* __fw_topology_h */ | 95 | #endif /* __fw_topology_h */ |