summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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 5fc56fac970..5932c72f9e4 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 a2de680d9d5..216965615ee 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -23,31 +23,22 @@
#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;
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index bc8a3487c83..018c6b8afba 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 913bfe16088..0778077e9d8 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 */