diff options
| -rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 3 | ||||
| -rw-r--r-- | drivers/i2c/i2c-boardinfo.c | 2 | ||||
| -rw-r--r-- | drivers/misc/eeprom/at24.c | 19 | 
3 files changed, 23 insertions, 1 deletions
| diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 9e12a53ef7b8..8eac00efadc1 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1617,6 +1617,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)  	/* Default timeout in interrupt mode: 200 ms */  	priv->adapter.timeout = HZ / 5; +	if (dev->irq == IRQ_NOTCONNECTED) +		priv->features &= ~FEATURE_IRQ; +  	if (priv->features & FEATURE_IRQ) {  		u16 pcictl, pcists; diff --git a/drivers/i2c/i2c-boardinfo.c b/drivers/i2c/i2c-boardinfo.c index 31186ead5a40..509a6007cdf6 100644 --- a/drivers/i2c/i2c-boardinfo.c +++ b/drivers/i2c/i2c-boardinfo.c @@ -86,6 +86,7 @@ int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsig  					property_entries_dup(info->properties);  			if (IS_ERR(devinfo->board_info.properties)) {  				status = PTR_ERR(devinfo->board_info.properties); +				kfree(devinfo);  				break;  			}  		} @@ -98,6 +99,7 @@ int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsig  					GFP_KERNEL);  			if (!devinfo->board_info.resources) {  				status = -ENOMEM; +				kfree(devinfo);  				break;  			}  		} diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index e0b4b36ef010..305a7a464d09 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -425,7 +425,8 @@ static ssize_t at24_eeprom_read_mac(struct at24_data *at24, char *buf,  	memset(msg, 0, sizeof(msg));  	msg[0].addr = client->addr;  	msg[0].buf = addrbuf; -	addrbuf[0] = 0x90 + offset; +	/* EUI-48 starts from 0x9a, EUI-64 from 0x98 */ +	addrbuf[0] = 0xa0 - at24->chip.byte_len + offset;  	msg[0].len = 1;  	msg[1].addr = client->addr;  	msg[1].flags = I2C_M_RD; @@ -568,6 +569,9 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count)  	if (unlikely(!count))  		return count; +	if (off + count > at24->chip.byte_len) +		return -EINVAL; +  	client = at24_translate_offset(at24, &off);  	ret = pm_runtime_get_sync(&client->dev); @@ -613,6 +617,9 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count)  	if (unlikely(!count))  		return -EINVAL; +	if (off + count > at24->chip.byte_len) +		return -EINVAL; +  	client = at24_translate_offset(at24, &off);  	ret = pm_runtime_get_sync(&client->dev); @@ -730,6 +737,16 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)  		dev_warn(&client->dev,  			"page_size looks suspicious (no power of 2)!\n"); +	/* +	 * REVISIT: the size of the EUI-48 byte array is 6 in at24mac402, while +	 * the call to ilog2() in AT24_DEVICE_MAGIC() rounds it down to 4. +	 * +	 * Eventually we'll get rid of the magic values altoghether in favor of +	 * real structs, but for now just manually set the right size. +	 */ +	if (chip.flags & AT24_FLAG_MAC && chip.byte_len == 4) +		chip.byte_len = 6; +  	/* Use I2C operations unless we're stuck with SMBus extensions. */  	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {  		if (chip.flags & AT24_FLAG_ADDR16) | 
