From: Michael Hunold <hunold@linuxtv.org>
To: akpm@osdl.org, torvalds@osdl.org, linux-kernel@vger.kernel.org
Subject: [PATCH 8/12] Add firmware loading support to av7110 driver
Date: Fri, 19 Dec 2003 13:28:42 +0100 [thread overview]
Message-ID: <10718369223748@convergence.de> (raw)
In-Reply-To: <10718369223835@convergence.de>
DVB: - use new firmware_class firmware loading facilities in dvb-ttpci/av7110 driver
--- linux-2.6.0-test11-bk8/drivers/media/dvb/ttpci/av7110.c.orig 2003-12-10 10:28:31.000000000 +0100
+++ linux-2.6.0-test11-bk8/drivers/media/dvb/ttpci/av7110.c 2003-12-11 12:06:18.000000000 +0100
@@ -60,6 +60,8 @@
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/firmware.h>
+#include <linux/crc32.h>
#include <asm/system.h>
#include <asm/bitops.h>
@@ -1971,8 +1973,6 @@ static u8 bootcode[] = {
0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00,
};
-#include "av7110_firm.h"
-
static int bootarm(struct av7110 *av7110)
{
struct saa7146_dev *dev= av7110->dev;
@@ -2025,7 +2025,7 @@ static int bootarm(struct av7110 *av7110
DEB_D(("bootarm: load dram code\n"));
- if (load_dram(av7110, (u32 *)Root, sizeof(Root))<0)
+ if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root)<0)
return -1;
saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
@@ -2033,7 +2033,7 @@ static int bootarm(struct av7110 *av7110
DEB_D(("bootarm: load dpram code\n"));
- mwdebi(av7110, DEBISWAB, DPRAM_BASE, Dpram, sizeof(Dpram));
+ mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);
wait_for_debi_done(av7110);
@@ -4502,22 +4502,91 @@ static struct saa7146_ext_vv av7110_vv_d
static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
{
+ const struct firmware *fw;
struct av7110 *av7110 = NULL;
int ret = 0;
-
+ u32 crc = 0, len = 0;
+ unsigned char *ptr;
+
+ DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
+
+ /* request the av7110 firmware, this will block until someone uploads it */
+ ret = request_firmware(&fw, "dvb-ttpci-01.fw", &dev->pci->dev);
+ if ( 0 != ret ) {
+ printk("dvb-ttpci: cannot request firmware!\n");
+ return -EINVAL;
+ }
+
+ if (fw->size <= 200000) {
+ printk("dvb-ttpci: this firmware is way too small.\n");
+ return -EINVAL;
+ }
+
+ /* prepare the av7110 device struct */
if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) {
printk ("%s: out of memory!\n", __FUNCTION__);
return -ENOMEM;
}
-
memset(av7110, 0, sizeof(struct av7110));
+
+ /* check if the firmware is available */
+ av7110->bin_fw = (unsigned char*)vmalloc(fw->size);
+ if (NULL == av7110->bin_fw) {
+ DEB_D(("out of memory\n"));
+ kfree(av7110);
+ return -ENOMEM;
+ }
+ memcpy(av7110->bin_fw, fw->data, fw->size);
+ av7110->size_fw = fw->size;
+ /* check for firmware magic */
+ ptr = av7110->bin_fw;
+ if (ptr[0] != 'A' || ptr[1] != 'V' ||
+ ptr[2] != 'F' || ptr[3] != 'W') {
+ printk("dvb-ttpci: this is not an av7110 firmware\n");
+ goto fw_error;
+ }
+ ptr += 4;
+
+ /* check dpram file */
+ crc = ntohl(*(u32*)ptr);
+ ptr += 4;
+ len = ntohl(*(u32*)ptr);
+ ptr += 4;
+ if (len >= 512) {
+ printk("dvb-ttpci: dpram file is way to big.\n");
+ goto fw_error;
+ }
+ if( crc != crc32_le(0,ptr,len)) {
+ printk("dvb-ttpci: crc32 of dpram file does not match.\n");
+ goto fw_error;
+ }
+ av7110->bin_dpram = ptr;
+ av7110->size_dpram = len;
+ ptr += len;
+
+ /* check root file */
+ crc = ntohl(*(u32*)ptr);
+ ptr += 4;
+ len = ntohl(*(u32*)ptr);
+ ptr += 4;
+
+ if (len <= 200000 || len >= 300000 || len > ((av7110->bin_fw+av7110->size_fw)-ptr) ) {
+ printk("dvb-ttpci: root file has strange size (%d). aborting.\n",len);
+ goto fw_error;
+ }
+ if( crc != crc32_le(0,ptr,len)) {
+ printk("dvb-ttpci: crc32 of dpram file does not match.\n");
+ goto fw_error;
+ }
+ av7110->bin_root = ptr;
+ av7110->size_root = len;
+
+ /* go on with regular device initialization */
av7110->card_name = (char*)pci_ext->ext_priv;
+ av7110->dev=(struct saa7146_dev *)dev;
(struct av7110*)dev->ext_priv = av7110;
- DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
-
- av7110->dev=(struct saa7146_dev *)dev;
dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name);
/* the Siemens DVB needs this if you want to have the i2c chips
@@ -4758,6 +4827,7 @@ static int av7110_attach (struct saa7146
}
printk(KERN_INFO "av7110: found av7110-%d.\n",av7110_num);
+ av7110->device_initialized = 1;
av7110_num++;
return 0;
@@ -4781,12 +4851,20 @@ err:
dvb_unregister_adapter (av7110->dvb_adapter);
return ret;
+fw_error:
+ vfree(av7110->bin_fw);
+ kfree(av7110);
+ return -EINVAL;
}
static int av7110_detach (struct saa7146_dev* saa)
{
struct av7110 *av7110 = (struct av7110*)saa->ext_priv;
DEB_EE(("av7110: %p\n",av7110));
+
+ if( 0 == av7110->device_initialized ) {
+ return 0;
+ }
saa7146_unregister_device(&av7110->v4l_dev, saa);
if (2 == av7110->has_analog_tuner) {
@@ -4817,11 +4895,13 @@ static int av7110_detach (struct saa7146
dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id);
dvb_unregister_adapter (av7110->dvb_adapter);
+ av7110_num--;
+ if (NULL != av7110->bin_fw ) {
+ vfree(av7110->bin_fw);
+ }
kfree (av7110);
-
saa->ext_priv = NULL;
- av7110_num--;
-
+
return 0;
}
--- linux-2.6.0-test11-bk8/drivers/media/dvb/ttpci/av7110.h.orig 2003-10-15 13:18:08.000000000 +0200
+++ linux-2.6.0-test11-bk8/drivers/media/dvb/ttpci/av7110.h 2003-12-11 12:05:05.000000000 +0100
@@ -1,8 +1,6 @@
#ifndef _AV7110_H_
#define _AV7110_H_
-#define DVB_FIRM_PATH "/lib/DVB/"
-
#include <linux/interrupt.h>
#include <linux/socket.h>
#include <linux/netdevice.h>
@@ -545,6 +543,18 @@ struct av7110 {
int dsp_dev;
u32 ir_config;
+
+ /* firmware stuff */
+ unsigned int device_initialized;
+
+ unsigned char *bin_fw;
+ unsigned long size_fw;
+
+ unsigned char *bin_dpram;
+ unsigned long size_dpram;
+
+ unsigned char *bin_root;
+ unsigned long size_root;
};
next prev parent reply other threads:[~2003-12-19 12:38 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-12-19 12:28 [PATCH 0/12] LinuxTV.org DVB+V4L fixes Michael Hunold
2003-12-19 12:28 ` [PATCH 1/12] Remove firmware of av7110 driver Michael Hunold
2003-12-19 12:28 ` [PATCH 2/12] Update saa7146 capture core Michael Hunold
2003-12-19 12:28 ` [PATCH 3/12] Add new DVB driver Michael Hunold
2003-12-19 12:28 ` [PATCH 4/12] Update Skystar2 " Michael Hunold
2003-12-19 12:28 ` [PATCH 5/12] Update DVB core Michael Hunold
2003-12-19 12:28 ` [PATCH 6/12] Update DVB frontend drivers Michael Hunold
2003-12-19 12:28 ` [PATCH 7/12] Update av7110 driver Michael Hunold
2003-12-19 12:28 ` Michael Hunold [this message]
2003-12-19 12:28 ` [PATCH 9/12] Update TTUSB DEC driver Michael Hunold
2003-12-19 12:28 ` [PATCH 10/12] Cleanup patch to remove 2.4 crud Michael Hunold
2003-12-19 12:28 ` [PATCH 11/12] Firmware_class update Michael Hunold
2003-12-19 12:28 ` [PATCH 12/12] Add DVB documentation Michael Hunold
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=10718369223748@convergence.de \
--to=hunold@linuxtv.org \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox