#define CMOS_ADJUST_CHECKSUM 1
#define CMOS_VERIFY_CHECKSUM 2
#define CMOS_BANK1_CRC_OFFSET 0x1E
/*
* Ioctls to adjust and verify CRC16s.
*/
static int
cmos_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
unsigned short crc = 0;
unsigned char buf;
switch (cmd) {
case CMOS_ADJUST_CHECKSUM:
/* Calculate the CRC of bank0 using a seed of 0 */
crc = adjust_cmos_crc(0, 0);
/* Seed bank1 with CRC of bank0 */
crc = adjust_cmos_crc(1, crc);
/* Store calculated CRC */
port_data_out(CMOS_BANK1_CRC_OFFSET,
(unsigned char)(crc & 0xFF), 1);
port_data_out((CMOS_BANK1_CRC_OFFSET + 1),
(unsigned char) (crc >> 8), 1);
break;
case CMOS_VERIFY_CHECKSUM:
/* Calculate the CRC of bank0 using a seed of 0 */
crc = adjust_cmos_crc(0, 0);
/* Seed bank1 with CRC of bank0 */
crc = adjust_cmos_crc(1, crc);
/* Compare the calculated CRC with the stored CRC */
buf = port_data_in(CMOS_BANK1_CRC_OFFSET, 1);
if (buf != (unsigned char) (crc & 0xFF)) return -EINVAL;
buf = port_data_in((CMOS_BANK1_CRC_OFFSET+1), 1);
if (buf != (unsigned char)(crc >> 8)) return -EINVAL;
break;
default:
return -EIO;
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1