firewire: Use lib/ implementation of CRC ITU-T.
authorKristian Høgsberg <krh@redhat.com>
Tue, 8 May 2007 00:33:31 +0000 (20:33 -0400)
committerStefan Richter <stefanr@s5r6.in-berlin.de>
Thu, 10 May 2007 16:24:13 +0000 (18:24 +0200)
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)
drivers/firewire/Kconfig
drivers/firewire/fw-card.c
drivers/firewire/fw-topology.c
drivers/firewire/fw-topology.h

index 5fc56fac97006325507a1bdafdcb291d0b7707eb..5932c72f9e424a1ad76a4c6f56f15e10709af855 100644 (file)
@@ -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
index a2de680d9d52e69715b732a56e6e97c21c429fa6..216965615ee8979d9d491139cd7dcfbf220a5588 100644 (file)
 #include <linux/errno.h>
 #include <linux/device.h>
 #include <linux/rwsem.h>
+#include <linux/crc-itu-t.h>
 #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;
-
-       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;
-       }
+       __be32 be32_block[256];
+       int i, length;
 
-       return crc;
+       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 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;
 
index bc8a3487c83a8fc21d4c96528dbe8b717acb162e..018c6b8afba64ada588b809cf76b6836b89a9d43 100644 (file)
@@ -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
index 913bfe160882e525104bd591b618661e6d5f5b9e..0778077e9d800f05f52070a415d0aa7d53d68585 100644 (file)
@@ -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 */