diff options
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-cards.c | 9 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-i2c.c | 35 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx.h | 2 |
3 files changed, 31 insertions, 15 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index f371dbede27e..331d55034616 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2739,6 +2739,9 @@ static void em28xx_card_setup(struct em28xx *dev) case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: { struct tveeprom tv; + + if (dev->eedata == NULL) + break; #if defined(CONFIG_MODULES) && defined(MODULE) request_module("tveeprom"); #endif @@ -2792,7 +2795,7 @@ static void em28xx_card_setup(struct em28xx *dev) em28xx_set_mode(dev, EM28XX_ANALOG_MODE); break; -/* + /* * The Dikom DK300 is detected as an Kworld VS-DVB-T 323UR. * * This occurs because they share identical USB vendor and @@ -2827,6 +2830,10 @@ static void em28xx_card_setup(struct em28xx *dev) "addresses)\n\n"); } + /* Free eeprom data memory */ + kfree(dev->eedata); + dev->eedata = NULL; + /* Allow override tuner type by a module parameter */ if (tuner >= 0) dev->tuner_type = tuner; diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 438cfbcb9bf5..8d4817747bf2 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -409,27 +409,33 @@ static int em28xx_i2c_read_block(struct em28xx *dev, u16 addr, bool addr_w16, return len; } -static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) +static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char **eedata, int len) { - unsigned char buf, *p = eedata; - struct em28xx_eeprom *em_eeprom = (void *)eedata; + u8 buf, *data; + struct em28xx_eeprom *em_eeprom; int i, err; + *eedata = NULL; + dev->i2c_client.addr = 0xa0 >> 1; /* Check if board has eeprom */ err = i2c_master_recv(&dev->i2c_client, &buf, 0); if (err < 0) { em28xx_info("board has no eeprom\n"); - memset(eedata, 0, len); return -ENODEV; } + data = kzalloc(len, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + /* Read EEPROM content */ err = em28xx_i2c_read_block(dev, 0x0000, dev->eeprom_addrwidth_16bit, - len, p); + len, data); if (err != len) { em28xx_errdev("failed to read eeprom (err=%d)\n", err); + kfree(data); return err; } @@ -441,19 +447,19 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) else em28xx_info("i2c eeprom %02x:", i); } - printk(" %02x", eedata[i]); + printk(" %02x", data[i]); if (15 == (i % 16)) printk("\n"); } if (dev->eeprom_addrwidth_16bit && - eedata[0] == 0x26 && eedata[3] == 0x00) { + data[0] == 0x26 && data[3] == 0x00) { /* new eeprom format; size 4-64kb */ - dev->hash = em28xx_hash_mem(eedata, len, 32); + dev->hash = em28xx_hash_mem(data, len, 32); em28xx_info("EEPROM hash = 0x%08lx\n", dev->hash); em28xx_info("EEPROM info: boot page address = 0x%02x04, " "boot configuration = 0x%02x\n", - eedata[1], eedata[2]); + data[1], data[2]); /* boot configuration (address 0x0002): * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz * [1] always selects 12 kb RAM @@ -471,13 +477,16 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) */ return 0; - } else if (em_eeprom->id[0] != 0x1a || em_eeprom->id[1] != 0xeb || - em_eeprom->id[2] != 0x67 || em_eeprom->id[3] != 0x95) { + } else if (data[0] != 0x1a || data[1] != 0xeb || + data[2] != 0x67 || data[3] != 0x95) { em28xx_info("unknown eeprom format or eeprom corrupted !\n"); return -ENODEV; } - dev->hash = em28xx_hash_mem(eedata, len, 32); + *eedata = data; + em_eeprom = (void *)eedata; + + dev->hash = em28xx_hash_mem(data, len, 32); em28xx_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", em_eeprom->id[0], em_eeprom->id[1], @@ -635,7 +644,7 @@ int em28xx_i2c_register(struct em28xx *dev) dev->i2c_client = em28xx_client_template; dev->i2c_client.adapter = &dev->i2c_adap; - retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata)); + retval = em28xx_i2c_eeprom(dev, &dev->eedata, 256); if ((retval < 0) && (retval != -ENODEV)) { em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", __func__, retval); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 139dfe54a057..77f600dc0067 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -562,7 +562,7 @@ struct em28xx { /* resources in use */ unsigned int resources; - unsigned char eedata[256]; + u8 *eedata; /* currently always 256 bytes */ /* Isoc control struct */ struct em28xx_dmaqueue vidq; |