From e175569c4639872b5cf242c9d4a71cc40c5f3c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Mon, 7 May 2007 20:33:31 -0400 Subject: [PATCH] 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 Signed-off-by: Stefan Richter (fixed Kconfig) --- drivers/firewire/Kconfig | 1 + drivers/firewire/fw-card.c | 33 +++++++++++---------------------- drivers/firewire/fw-topology.c | 5 ++--- drivers/firewire/fw-topology.h | 5 +++-- 4 files changed, 17 insertions(+), 27 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" config FIREWIRE tristate "IEEE 1394 (FireWire) support (JUJU alternative stack, experimental)" depends on EXPERIMENTAL + select CRC_ITU_T help IEEE 1394 describes a high performance serial bus, which is also 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 @@ #include #include #include +#include #include "fw-transaction.h" #include "fw-topology.h" #include "fw-device.h" -/* The lib/crc16.c implementation uses the standard (0x8005) - * polynomial, but we need the ITU-T (or CCITT) polynomial (0x1021). - * The implementation below works on an array of host-endian u32 - * words, assuming they'll be transmited msb first. */ -u16 -crc16_itu_t(const u32 *buffer, size_t length) +int fw_compute_block_crc(u32 *block) { - int shift, i; - u32 data; - u16 sum, crc = 0; + __be32 be32_block[256]; + int i, length; - for (i = 0; i < length; i++) { - data = *buffer++; - for (shift = 28; shift >= 0; shift -= 4 ) { - sum = ((crc >> 12) ^ (data >> shift)) & 0xf; - crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum); - } - crc &= 0xffff; - } + length = (*block >> 16) & 0xff; + for (i = 0; i < length; i++) + be32_block[i] = cpu_to_be32(block[i + 1]); + *block |= crc_itu_t(0, (u8 *) be32_block, length * 4); - return crc; + return length; } static DECLARE_RWSEM(card_rwsem); @@ -126,10 +117,8 @@ generate_config_rom (struct fw_card *card, size_t *config_rom_length) * assumes that CRC length and info length are identical for * the bus info block, which is always the case for this * implementation. */ - for (i = 0; i < j; i += length + 1) { - length = (config_rom[i] >> 16) & 0xff; - config_rom[i] |= crc16_itu_t(&config_rom[i + 1], length); - } + for (i = 0; i < j; i += length + 1) + length = fw_compute_block_crc(config_rom + i); *config_rom_length = j; 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 update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count) { int node_count; - u32 crc; card->topology_map[1]++; node_count = (card->root_node->node_id & 0x3f) + 1; card->topology_map[2] = (node_count << 16) | self_id_count; - crc = crc16_itu_t(card->topology_map + 1, self_id_count + 2); - card->topology_map[0] = ((self_id_count + 2) << 16) | crc; + card->topology_map[0] = (self_id_count + 2) << 16; memcpy(&card->topology_map[3], self_ids, self_id_count * 4); + fw_compute_block_crc(card->topology_map); } 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) void fw_destroy_nodes(struct fw_card *card); -u16 -crc16_itu_t(const u32 *buffer, size_t length); +int +fw_compute_block_crc(u32 *block); + #endif /* __fw_topology_h */