Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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)

authored by

Kristian Høgsberg and committed by
Stefan Richter
e175569c 3e7cbae7

+17 -27
+1
drivers/firewire/Kconfig
··· 6 6 config FIREWIRE 7 7 tristate "IEEE 1394 (FireWire) support (JUJU alternative stack, experimental)" 8 8 depends on EXPERIMENTAL 9 + select CRC_ITU_T 9 10 help 10 11 IEEE 1394 describes a high performance serial bus, which is also 11 12 known as FireWire(tm) or i.Link(tm) and is used for connecting all
+11 -22
drivers/firewire/fw-card.c
··· 23 23 #include <linux/errno.h> 24 24 #include <linux/device.h> 25 25 #include <linux/rwsem.h> 26 + #include <linux/crc-itu-t.h> 26 27 #include "fw-transaction.h" 27 28 #include "fw-topology.h" 28 29 #include "fw-device.h" 29 30 30 - /* The lib/crc16.c implementation uses the standard (0x8005) 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) 31 + int fw_compute_block_crc(u32 *block) 36 32 { 37 - int shift, i; 38 - u32 data; 39 - u16 sum, crc = 0; 33 + __be32 be32_block[256]; 34 + int i, length; 40 35 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 - } 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); 49 40 50 - return crc; 41 + return length; 51 42 } 52 43 53 44 static DECLARE_RWSEM(card_rwsem); ··· 117 126 * assumes that CRC length and info length are identical for 118 127 * the bus info block, which is always the case for this 119 128 * implementation. */ 120 - for (i = 0; i < j; i += length + 1) { 121 - length = (config_rom[i] >> 16) & 0xff; 122 - config_rom[i] |= crc16_itu_t(&config_rom[i + 1], length); 123 - } 129 + for (i = 0; i < j; i += length + 1) 130 + length = fw_compute_block_crc(config_rom + i); 124 131 125 132 *config_rom_length = j; 126 133
+2 -3
drivers/firewire/fw-topology.c
··· 465 465 update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count) 466 466 { 467 467 int node_count; 468 - u32 crc; 469 468 470 469 card->topology_map[1]++; 471 470 node_count = (card->root_node->node_id & 0x3f) + 1; 472 471 card->topology_map[2] = (node_count << 16) | self_id_count; 473 - crc = crc16_itu_t(card->topology_map + 1, self_id_count + 2); 474 - card->topology_map[0] = ((self_id_count + 2) << 16) | crc; 472 + card->topology_map[0] = (self_id_count + 2) << 16; 475 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 477 void
+3 -2
drivers/firewire/fw-topology.h
··· 88 88 void 89 89 fw_destroy_nodes(struct fw_card *card); 90 90 91 - u16 92 - crc16_itu_t(const u32 *buffer, size_t length); 91 + int 92 + fw_compute_block_crc(u32 *block); 93 + 93 94 94 95 #endif /* __fw_topology_h */