Skip to content

Commit

Permalink
Staging: ipack: check the device ID space CRC.
Browse files Browse the repository at this point in the history
We check the CRC and store the result of the check in struct ipac_device.
A warning is emitted if the check fails.  However we leave it to the
IPack module device to refuse to initialize due to a bad CRC.  I have seen
otherwise good modules with bad CRCs.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Jens Taprogge authored and Greg Kroah-Hartman committed Sep 11, 2012
1 parent 8a3ae16 commit a92caeb
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
59 changes: 58 additions & 1 deletion drivers/staging/ipack/ipack.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,27 +253,84 @@ void ipack_driver_unregister(struct ipack_driver *edrv)
}
EXPORT_SYMBOL_GPL(ipack_driver_unregister);

static u16 ipack_crc_byte(u16 crc, u8 c)
{
int i;

crc ^= c << 8;
for (i = 0; i < 8; i++)
crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0);
return crc;
}

/*
* The algorithm in lib/crc-ccitt.c does not seem to apply since it uses the
* opposite bit ordering.
*/
static u8 ipack_calc_crc1(struct ipack_device *dev)
{
u8 c;
u16 crc;
unsigned int i;

crc = 0xffff;
for (i = 0; i < dev->id_avail; i++) {
c = (i != 11) ? dev->id[i] : 0;
crc = ipack_crc_byte(crc, c);
}
crc = ~crc;
return crc & 0xff;
}

static u16 ipack_calc_crc2(struct ipack_device *dev)
{
u8 c;
u16 crc;
unsigned int i;

crc = 0xffff;
for (i = 0; i < dev->id_avail; i++) {
c = ((i != 0x18) && (i != 0x19)) ? dev->id[i] : 0;
crc = ipack_crc_byte(crc, c);
}
crc = ~crc;
return crc;
}

static void ipack_parse_id1(struct ipack_device *dev)
{
u8 *id = dev->id;
u8 crc;

dev->id_vendor = id[4];
dev->id_device = id[5];
dev->speed_8mhz = 1;
dev->speed_32mhz = (id[7] == 'H');
crc = ipack_calc_crc1(dev);
dev->id_crc_correct = (crc == id[11]);
if (!dev->id_crc_correct) {
dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n",
id[11], crc);
}
}

static void ipack_parse_id2(struct ipack_device *dev)
{
__be16 *id = (__be16 *) dev->id;
u16 flags;
u16 flags, crc;

dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16)
+ be16_to_cpu(id[4]);
dev->id_device = be16_to_cpu(id[5]);
flags = be16_to_cpu(id[10]);
dev->speed_8mhz = !!(flags & 2);
dev->speed_32mhz = !!(flags & 4);
crc = ipack_calc_crc2(dev);
dev->id_crc_correct = (crc == be16_to_cpu(id[12]));
if (!dev->id_crc_correct) {
dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n",
id[11], crc);
}
}

static int ipack_device_read_id(struct ipack_device *dev)
Expand Down
1 change: 1 addition & 0 deletions drivers/staging/ipack/ipack.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ struct ipack_device {
u32 id_vendor;
u32 id_device;
u8 id_format;
unsigned int id_crc_correct:1;
unsigned int speed_8mhz:1;
unsigned int speed_32mhz:1;
};
Expand Down

0 comments on commit a92caeb

Please sign in to comment.