From patchwork Fri Mar 1 23:12:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Frank_Sch=C3=A4fer?= X-Patchwork-Id: 2205221 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id CF9233FCF6 for ; Fri, 1 Mar 2013 23:11:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752151Ab3CAXLw (ORCPT ); Fri, 1 Mar 2013 18:11:52 -0500 Received: from mail-ee0-f46.google.com ([74.125.83.46]:55957 "EHLO mail-ee0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752060Ab3CAXLv (ORCPT ); Fri, 1 Mar 2013 18:11:51 -0500 Received: by mail-ee0-f46.google.com with SMTP id e49so2701344eek.5 for ; Fri, 01 Mar 2013 15:11:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:mime-version:content-type:content-transfer-encoding; bh=hFTy6iGFJkry4djpmcl96TdtZ5msYLQnG93xy2vvp8A=; b=GJvGinQ1WK3CcY5goHnxIUjwl+Pl/bhW62RITQ9GAm9YrHLXDyojYyH0p7HXfXRH+Y Kg8yszv3xHM8SejBwta43HrGUS35eQbNF+LBbMFotCFZ1mnqr2erSMcSolcZIr3uijXm dkZbQkKSplLGumI5deyKN2ofb6VrUvc9JJhF7/K7G6R0tqrJPnB2okpMmwV2/VkfTkTD zi+Rmhe+Nodyjotl3rVGgbIyUiGQTLeK5SIv2jZQCU6kcKWVafjqPDVFqxMdH7FAmLR1 TAEa9ZgNgCqbIDbgCwSE+YaCtNBtsY2SYyWj+nQAxXXOALJIXbdxS63eTAulPOIIU1/W nEMA== X-Received: by 10.14.223.69 with SMTP id u45mr32305874eep.23.1362179510094; Fri, 01 Mar 2013 15:11:50 -0800 (PST) Received: from Athlon64X2-5000.site (ip-178-201-83-213.unitymediagroup.de. [178.201.83.213]) by mx.google.com with ESMTPS id d47sm19488041eem.9.2013.03.01.15.11.48 (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 01 Mar 2013 15:11:49 -0800 (PST) From: =?UTF-8?q?Frank=20Sch=C3=A4fer?= To: mchehab@redhat.com Cc: linux-media@vger.kernel.org, =?UTF-8?q?Frank=20Sch=C3=A4fer?= Subject: [PATCH 09/11] em28xx: do not store eeprom content permanently Date: Sat, 2 Mar 2013 00:12:13 +0100 Message-Id: <1362179535-18929-10-git-send-email-fschaefer.oss@googlemail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1362179535-18929-1-git-send-email-fschaefer.oss@googlemail.com> References: <1362179535-18929-1-git-send-email-fschaefer.oss@googlemail.com> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org We currently reserve an array of 256 bytes for the eeprom content in the device struct. For eeproms with 16 bit address width it might even be necessary to increase the buffer size further. Having such a big chunk of memory reserved even if the device has no eeprom and keeping it after it has already been processed seems to be a waste of memory. Change the code to allocate + free the eeprom memory dynamically. This also makes it possible to handle different dataset sizes depending on what is stored/found in the eeprom. Signed-off-by: Frank Schäfer --- drivers/media/usb/em28xx/em28xx-cards.c | 9 +++++++- drivers/media/usb/em28xx/em28xx-i2c.c | 35 +++++++++++++++++++------------ drivers/media/usb/em28xx/em28xx.h | 2 +- 3 Dateien geändert, 31 Zeilen hinzugefügt(+), 15 Zeilen entfernt(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index fa51f81..2e3d3ad 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2743,6 +2743,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 @@ -2796,7 +2799,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 @@ -2831,6 +2834,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 a3e9547..dfbc22e 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -405,27 +405,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; } @@ -437,19 +443,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 @@ -467,13 +473,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], @@ -631,7 +640,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 139dfe5..77f600d 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;