diff options
author | Michael Hunold <devnull@localhost> | 2003-12-21 15:18:44 +0000 |
---|---|---|
committer | Michael Hunold <devnull@localhost> | 2003-12-21 15:18:44 +0000 |
commit | 56325ebe82f12b17a36ee96f5c0f4604dbd9dbe6 (patch) | |
tree | 594d7de4f48086a43cb34e159b1422d2de551256 /linux | |
parent | 28eae47f376c13563c02c2c3a368b20951c45009 (diff) | |
download | mediapointer-dvb-s2-56325ebe82f12b17a36ee96f5c0f4604dbd9dbe6.tar.gz mediapointer-dvb-s2-56325ebe82f12b17a36ee96f5c0f4604dbd9dbe6.tar.bz2 |
- apply dvb-ttpci/av7110 firmware removal from 2.6.0 patch here, too, but:
the firmware is still compiled into the driver for 2.4 by default,
the necessary files are created dynamically from the firmware file.
get it from http://www.linuxtv.org/download/dvb/dvb-ttpci-01.fw
- revamp fdump utility to be smarter when the source file isn't there
Diffstat (limited to 'linux')
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.c | 121 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.h | 14 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttusb-dec/fdump.c | 64 |
3 files changed, 157 insertions, 42 deletions
diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 2b30ba183..480752351 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -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); @@ -4500,24 +4500,110 @@ static u8 saa7113_init_regs[] = { static struct saa7146_ext_vv av7110_vv_data_st; static struct saa7146_ext_vv av7110_vv_data_c; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +#include "av7110_firm.h" +#endif + static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) { + 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)); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) + /* 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; + } +#else + fw = vmalloc(sizeof(struct firmware)); + if (NULL == fw) { + printk("dvb-ttpci: not enough memory\n"); + return -ENOMEM; + } + fw->size = sizeof(dvb_ttpci_fw); + fw->data = dvb_ttpci_fw; +#endif + + 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; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + vfree(fw); +#endif + /* 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 +4844,7 @@ static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_ } printk(KERN_INFO "av7110: found av7110-%d.\n",av7110_num); + av7110->device_initialized = 1; av7110_num++; return 0; @@ -4781,12 +4868,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 +4912,13 @@ static int av7110_detach (struct saa7146_dev* saa) 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; } diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h index da8a9ad32..3c76b0325 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.h +++ b/linux/drivers/media/dvb/ttpci/av7110.h @@ -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; }; diff --git a/linux/drivers/media/dvb/ttusb-dec/fdump.c b/linux/drivers/media/dvb/ttusb-dec/fdump.c index 834314a45..0b478db3e 100644 --- a/linux/drivers/media/dvb/ttusb-dec/fdump.c +++ b/linux/drivers/media/dvb/ttusb-dec/fdump.c @@ -4,33 +4,41 @@ #include <fcntl.h> #include <unistd.h> - -int main (int argc, char **argv) +int main(int argc, char **argv) { - unsigned char buf[8]; - unsigned int i, count, bytes = 0; - int fd; - - if (argc != 3) { - fprintf (stderr, "\n\tusage: %s <ucode.bin> <array_name>\n\n", - argv[0]); - return -1; - } - - fd = open (argv[1], O_RDONLY); - - printf ("\n#include <asm/types.h>\n\nu8 %s [] __initdata = {", - argv[2]); - - while ((count = read (fd, buf, 8)) > 0) { - printf ("\n\t"); - for (i=0;i<count;i++, bytes++) - printf ("0x%02x, ", buf[i]); - } - - printf ("\n};\n\n"); - close (fd); - - return 0; + unsigned char buf[8]; + unsigned int i, count, bytes = 0; + FILE *fd_in, *fd_out; + + if (argc != 4) { + fprintf(stderr, "\n\tusage: %s <ucode.bin> <array_name> <output_name>\n\n", argv[0]); + return -1; + } + + fd_in = fopen(argv[1], "rb"); + if (fd_in == NULL) { + fprintf(stderr, "firmware file '%s' not found\n", argv[1]); + return -1; + } + + fd_out = fopen(argv[3], "w+"); + if (fd_out == NULL) { + fprintf(stderr, "cannot create output file '%s'\n", argv[3]); + return -1; + } + + fprintf(fd_out, "\n#include <asm/types.h>\n\nu8 %s [] = {", argv[2]); + + while ((count = fread(buf, 1, 8, fd_in)) > 0) { + fprintf(fd_out, "\n\t"); + for (i = 0; i < count; i++, bytes++) + fprintf(fd_out, "0x%02x, ", buf[i]); + } + + fprintf(fd_out, "\n};\n\n"); + + fclose(fd_in); + fclose(fd_out); + + return 0; } - |