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 /drivers/firewire/fw-card.c | |
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)
Diffstat (limited to 'drivers/firewire/fw-card.c')
-rw-r--r-- | drivers/firewire/fw-card.c | 35 |
1 files changed, 12 insertions, 23 deletions
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 | ||