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

i2c-piix4: Various cleanups and minor fixes

The i2c-piix4 driver was used recently as a model to write a new SMBus
host controller driver and this made me realize that the code of this
old driver wasn't exactly good. So, here are many cleanups and minor
fixes to this driver, so that these minor mistakes aren't duplicated
again:

* Delete unused structure.
* Delete needless forward function declaration.
* Properly announce the SMBus host controller as we find it.
* Spell it SMBus not SMB.
* Return -EBUSY instead of -ENODEV when the I/O region is already in
use.
* Drop useless masks on the 7-bit address and the R/W bit.
* Reject block transaction requests with an invalid block length.
* Check and report block transaction replies with an invalid block
length.
* Delete a useless comment.

Signed-off-by: Jean Delvare <khali@linux-fr.org>

authored by

Jean Delvare and committed by
Jean Delvare
fa63cd56 97140342

+15 -26
+15 -26
drivers/i2c/busses/i2c-piix4.c
··· 42 42 #include <asm/io.h> 43 43 44 44 45 - struct sd { 46 - const unsigned short mfr; 47 - const unsigned short dev; 48 - const unsigned char fn; 49 - const char *name; 50 - }; 51 - 52 45 /* PIIX4 SMBus address offsets */ 53 46 #define SMBHSTSTS (0 + piix4_smba) 54 47 #define SMBHSLVSTS (1 + piix4_smba) ··· 94 101 "Forcibly enable the PIIX4 at the given address. " 95 102 "EXTREMELY DANGEROUS!"); 96 103 97 - static int piix4_transaction(void); 98 - 99 104 static unsigned short piix4_smba; 100 105 static int srvrworks_csb5_delay; 101 106 static struct pci_driver piix4_driver; ··· 132 141 { 133 142 unsigned char temp; 134 143 135 - dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev)); 136 - 137 144 if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) && 138 145 (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5)) 139 146 srvrworks_csb5_delay = 1; ··· 161 172 pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba); 162 173 piix4_smba &= 0xfff0; 163 174 if(piix4_smba == 0) { 164 - dev_err(&PIIX4_dev->dev, "SMB base address " 175 + dev_err(&PIIX4_dev->dev, "SMBus base address " 165 176 "uninitialized - upgrade BIOS or use " 166 177 "force_addr=0xaddr\n"); 167 178 return -ENODEV; ··· 169 180 } 170 181 171 182 if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { 172 - dev_err(&PIIX4_dev->dev, "SMB region 0x%x already in use!\n", 183 + dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", 173 184 piix4_smba); 174 - return -ENODEV; 185 + return -EBUSY; 175 186 } 176 187 177 188 pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp); ··· 217 228 "(or code out of date)!\n"); 218 229 219 230 pci_read_config_byte(PIIX4_dev, SMBREV, &temp); 220 - dev_dbg(&PIIX4_dev->dev, "SMBREV = 0x%X\n", temp); 221 - dev_dbg(&PIIX4_dev->dev, "SMBA = 0x%X\n", piix4_smba); 231 + dev_info(&PIIX4_dev->dev, 232 + "SMBus Host Controller at 0x%x, revision %d\n", 233 + piix4_smba, temp); 222 234 223 235 return 0; 224 236 } 225 237 226 - /* Another internally used function */ 227 238 static int piix4_transaction(void) 228 239 { 229 240 int temp; ··· 311 322 dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); 312 323 return -EOPNOTSUPP; 313 324 case I2C_SMBUS_QUICK: 314 - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 325 + outb_p((addr << 1) | read_write, 315 326 SMBHSTADD); 316 327 size = PIIX4_QUICK; 317 328 break; 318 329 case I2C_SMBUS_BYTE: 319 - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 330 + outb_p((addr << 1) | read_write, 320 331 SMBHSTADD); 321 332 if (read_write == I2C_SMBUS_WRITE) 322 333 outb_p(command, SMBHSTCMD); 323 334 size = PIIX4_BYTE; 324 335 break; 325 336 case I2C_SMBUS_BYTE_DATA: 326 - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 337 + outb_p((addr << 1) | read_write, 327 338 SMBHSTADD); 328 339 outb_p(command, SMBHSTCMD); 329 340 if (read_write == I2C_SMBUS_WRITE) ··· 331 342 size = PIIX4_BYTE_DATA; 332 343 break; 333 344 case I2C_SMBUS_WORD_DATA: 334 - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 345 + outb_p((addr << 1) | read_write, 335 346 SMBHSTADD); 336 347 outb_p(command, SMBHSTCMD); 337 348 if (read_write == I2C_SMBUS_WRITE) { ··· 341 352 size = PIIX4_WORD_DATA; 342 353 break; 343 354 case I2C_SMBUS_BLOCK_DATA: 344 - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 355 + outb_p((addr << 1) | read_write, 345 356 SMBHSTADD); 346 357 outb_p(command, SMBHSTCMD); 347 358 if (read_write == I2C_SMBUS_WRITE) { 348 359 len = data->block[0]; 349 - if (len < 0) 350 - len = 0; 351 - if (len > 32) 352 - len = 32; 360 + if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) 361 + return -EINVAL; 353 362 outb_p(len, SMBHSTDAT0); 354 363 i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ 355 364 for (i = 1; i <= len; i++) ··· 377 390 break; 378 391 case PIIX4_BLOCK_DATA: 379 392 data->block[0] = inb_p(SMBHSTDAT0); 393 + if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX) 394 + return -EPROTO; 380 395 i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ 381 396 for (i = 1; i <= data->block[0]; i++) 382 397 data->block[i] = inb_p(SMBBLKDAT);