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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.