mirror of
https://github.com/torvalds/linux.git
synced 2025-11-03 10:10:33 +02:00
Staging: ipack: check the device ID space CRC.
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>
This commit is contained in:
parent
8a3ae16e60
commit
a92caeb8e1
2 changed files with 59 additions and 1 deletions
|
|
@ -253,20 +253,71 @@ void ipack_driver_unregister(struct ipack_driver *edrv)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ipack_driver_unregister);
|
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)
|
static void ipack_parse_id1(struct ipack_device *dev)
|
||||||
{
|
{
|
||||||
u8 *id = dev->id;
|
u8 *id = dev->id;
|
||||||
|
u8 crc;
|
||||||
|
|
||||||
dev->id_vendor = id[4];
|
dev->id_vendor = id[4];
|
||||||
dev->id_device = id[5];
|
dev->id_device = id[5];
|
||||||
dev->speed_8mhz = 1;
|
dev->speed_8mhz = 1;
|
||||||
dev->speed_32mhz = (id[7] == 'H');
|
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)
|
static void ipack_parse_id2(struct ipack_device *dev)
|
||||||
{
|
{
|
||||||
__be16 *id = (__be16 *) dev->id;
|
__be16 *id = (__be16 *) dev->id;
|
||||||
u16 flags;
|
u16 flags, crc;
|
||||||
|
|
||||||
dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16)
|
dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16)
|
||||||
+ be16_to_cpu(id[4]);
|
+ be16_to_cpu(id[4]);
|
||||||
|
|
@ -274,6 +325,12 @@ static void ipack_parse_id2(struct ipack_device *dev)
|
||||||
flags = be16_to_cpu(id[10]);
|
flags = be16_to_cpu(id[10]);
|
||||||
dev->speed_8mhz = !!(flags & 2);
|
dev->speed_8mhz = !!(flags & 2);
|
||||||
dev->speed_32mhz = !!(flags & 4);
|
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)
|
static int ipack_device_read_id(struct ipack_device *dev)
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ struct ipack_device {
|
||||||
u32 id_vendor;
|
u32 id_vendor;
|
||||||
u32 id_device;
|
u32 id_device;
|
||||||
u8 id_format;
|
u8 id_format;
|
||||||
|
unsigned int id_crc_correct:1;
|
||||||
unsigned int speed_8mhz:1;
|
unsigned int speed_8mhz:1;
|
||||||
unsigned int speed_32mhz:1;
|
unsigned int speed_32mhz:1;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue