patch-2.4.20 linux-2.4.20/drivers/media/video/bttv-driver.c

Next file: linux-2.4.20/drivers/media/video/bttv-if.c
Previous file: linux-2.4.20/drivers/media/video/bttv-cards.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.19/drivers/media/video/bttv-driver.c linux-2.4.20/drivers/media/video/bttv-driver.c
@@ -43,6 +43,7 @@
 #include <linux/kmod.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
+#include <linux/pagemap.h>
 
 #include "bttvp.h"
 #include "tuner.h"
@@ -65,8 +66,10 @@
 static unsigned int radio[BTTV_MAX];
 static unsigned int fieldnr = 0;
 static unsigned int irq_debug = 0;
-static unsigned int gbuffers = 2;
+static unsigned int gbuffers = 4;
 static unsigned int gbufsize = BTTV_MAX_FBUF;
+static int latency = -1;
+
 static unsigned int combfilter = 0;
 static unsigned int lumafilter = 0;
 static unsigned int automute = 1;
@@ -80,7 +83,7 @@
 unsigned int bttv_gpio = 0;
 
 /* insmod options */
-MODULE_PARM(radio,"1-4i");
+MODULE_PARM(radio,"1-" __stringify(BTTV_MAX) "i");
 MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)");
 MODULE_PARM(bigendian,"i");
 MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian");
@@ -98,6 +101,8 @@
 MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (64 max)");
 MODULE_PARM(gbufsize,"i");
 MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
+MODULE_PARM(latency,"i");
+MODULE_PARM_DESC(latency,"pci latency timer");
 
 MODULE_PARM(combfilter,"i");
 MODULE_PARM(lumafilter,"i");
@@ -137,64 +142,14 @@
 /* Memory management functions */
 /*******************************/
 
-#define MDEBUG(x)	do { } while(0)		/* Debug memory management */
-
-/* [DaveM] I've recoded most of this so that:
- * 1) It's easier to tell what is happening
- * 2) It's more portable, especially for translating things
- *    out of vmalloc mapped areas in the kernel.
- * 3) Less unnecessary translations happen.
- *
- * The code used to assume that the kernel vmalloc mappings
- * existed in the page tables of every process, this is simply
- * not guarenteed.  We now use pgd_offset_k which is the
- * defined way to get at the kernel page tables.
- */
-
-/* Given PGD from the address space's page table, return the kernel
- * virtual mapping of the physical memory mapped at ADR.
- */
-static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
-{
-        unsigned long ret = 0UL;
-	pmd_t *pmd;
-	pte_t *ptep, pte;
-  
-	if (!pgd_none(*pgd)) {
-                pmd = pmd_offset(pgd, adr);
-                if (!pmd_none(*pmd)) {
-                        ptep = pte_offset(pmd, adr);
-                        pte = *ptep;
-                        if(pte_present(pte)) {
-				ret  = (unsigned long) page_address(pte_page(pte));
-				ret |= (adr & (PAGE_SIZE - 1));
-				
-			}
-                }
-        }
-        MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
-	return ret;
-}
-
-static inline unsigned long uvirt_to_bus(unsigned long adr) 
-{
-        unsigned long kva, ret;
-
-        kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
-	ret = virt_to_bus((void *)kva);
-        MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
-        return ret;
-}
 
 static inline unsigned long kvirt_to_bus(unsigned long adr) 
 {
-        unsigned long va, kva, ret;
+        unsigned long kva;
 
-        va = VMALLOC_VMADDR(adr);
-        kva = uvirt_to_kva(pgd_offset_k(va), va);
-	ret = virt_to_bus((void *)kva);
-        MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
-        return ret;
+	kva = (unsigned long)page_address(vmalloc_to_page((void *)adr));
+	kva |= adr & (PAGE_SIZE-1); /* restore the offset */   
+	return virt_to_bus((void *)kva);
 }
 
 /* Here we want the physical address of the memory.
@@ -203,19 +158,18 @@
  */
 static inline unsigned long kvirt_to_pa(unsigned long adr) 
 {
-        unsigned long va, kva, ret;
+        unsigned long kva;
 
-        va = VMALLOC_VMADDR(adr);
-        kva = uvirt_to_kva(pgd_offset_k(va), va);
-	ret = __pa(kva);
-        MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
-        return ret;
+	kva = (unsigned long)page_address(vmalloc_to_page((void *)adr));
+	kva |= adr & (PAGE_SIZE-1); /* restore the offset */
+	return __pa(kva);
 }
 
 static void * rvmalloc(signed long size)
 {
+	struct page *page;
 	void * mem;
-	unsigned long adr, page;
+	unsigned long adr;
 
 	mem=vmalloc_32(size);
 	if (NULL == mem)
@@ -224,10 +178,9 @@
 		/* Clear the ram out, no junk to the user */
 		memset(mem, 0, size);
 	        adr=(unsigned long) mem;
-		while (size > 0) 
-                {
-	                page = kvirt_to_pa(adr);
-			mem_map_reserve(virt_to_page(__va(page)));
+		while (size > 0) {
+			page = vmalloc_to_page((void *)adr);
+			mem_map_reserve(page);
 			adr+=PAGE_SIZE;
 			size-=PAGE_SIZE;
 		}
@@ -237,15 +190,14 @@
 
 static void rvfree(void * mem, signed long size)
 {
-        unsigned long adr, page;
+	struct page *page;
+        unsigned long adr;
         
-	if (mem) 
-	{
+	if (mem) {
 	        adr=(unsigned long) mem;
-		while (size > 0) 
-                {
-	                page = kvirt_to_pa(adr);
-			mem_map_unreserve(virt_to_page(__va(page)));
+		while (size > 0) {
+			page = vmalloc_to_page((void *)adr);
+			mem_map_unreserve(page);
 			adr+=PAGE_SIZE;
 			size-=PAGE_SIZE;
 		}
@@ -290,8 +242,10 @@
 
 static void audio(struct bttv *btv, int mode)
 {
-	btaor(bttv_tvcards[btv->type].gpiomask, ~bttv_tvcards[btv->type].gpiomask,
-              BT848_GPIO_OUT_EN);
+	if (bttv_tvcards[btv->type].gpiomask)
+		btaor(bttv_tvcards[btv->type].gpiomask,
+		      ~bttv_tvcards[btv->type].gpiomask,
+		      BT848_GPIO_OUT_EN);
 
 	switch (mode)
 	{
@@ -318,8 +272,10 @@
 	        mode=AUDIO_OFF;
         if ((mode == AUDIO_TUNER) && (btv->radio))
 		mode = AUDIO_RADIO;
-	btaor(bttv_tvcards[btv->type].audiomux[mode],
-              ~bttv_tvcards[btv->type].gpiomask, BT848_GPIO_DATA);
+	if (bttv_tvcards[btv->type].gpiomask)
+		btaor(bttv_tvcards[btv->type].audiomux[mode],
+		      ~bttv_tvcards[btv->type].gpiomask,
+		      BT848_GPIO_DATA);
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv,audio_modes[mode]);
 	if (!in_interrupt())
@@ -435,8 +391,10 @@
 static void bt848_muxsel(struct bttv *btv, unsigned int input)
 {
         /* needed by RemoteVideo MX */
-	btaor(bttv_tvcards[btv->type].gpiomask2,~bttv_tvcards[btv->type].gpiomask2,
-              BT848_GPIO_OUT_EN);
+	if (bttv_tvcards[btv->type].gpiomask2)
+		btaor(bttv_tvcards[btv->type].gpiomask2,
+		      ~bttv_tvcards[btv->type].gpiomask2,
+		      BT848_GPIO_OUT_EN);
 
 	/* This seems to get rid of some synchronization problems */
 	btand(~(3<<5), BT848_IFORM);
@@ -458,12 +416,14 @@
 	audio(btv, (input!=bttv_tvcards[btv->type].tuner) ?
               AUDIO_EXTERN : AUDIO_TUNER);
 
-	btaor(bttv_tvcards[btv->type].muxsel[input]>>4,
-		~bttv_tvcards[btv->type].gpiomask2, BT848_GPIO_DATA);
+	if (bttv_tvcards[btv->type].gpiomask2)
+		btaor(bttv_tvcards[btv->type].muxsel[input]>>4,
+		      ~bttv_tvcards[btv->type].gpiomask2,
+		      BT848_GPIO_DATA);
 
 	/* card specific hook */
-	if( bttv_tvcards[btv->type].muxsel_hook )
-		bttv_tvcards[btv->type].muxsel_hook ( btv, input );
+	if (bttv_tvcards[btv->type].muxsel_hook)
+		bttv_tvcards[btv->type].muxsel_hook(btv, input);
 
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv,"muxsel");
@@ -1255,7 +1215,8 @@
 static long bttv_read(struct video_device *v, char *buf, unsigned long count, int nonblock)
 {
 	struct bttv *btv= (struct bttv *)v;
-	int q,todo;
+	int q;
+	unsigned long todo;
 	DECLARE_WAITQUEUE(wait, current);
 
 	/* BROKEN: RETURNS VBI WHEN IT SHOULD RETURN GRABBED VIDEO FRAME */
@@ -1583,7 +1544,7 @@
 		bt848_muxsel(btv, v.channel);
 		btv->channel=v.channel;
 		if (btv->win.norm != v.norm) {
-			if(btv->type== BTTV_VOODOOTV_FM)
+			if (btv->type == BTTV_VOODOOTV_FM)
 				bttv_tda9880_setnorm(btv,v.norm);
 			btv->win.norm = v.norm;
 			make_vbitab(btv);
@@ -1874,8 +1835,8 @@
 		bttv_call_i2c_clients(btv,cmd,&v);
 
 		/* card specific hooks */
-		if (bttv_tvcards[btv->type].audio_hook)
-			bttv_tvcards[btv->type].audio_hook(btv,&v,0);
+		if (btv->audio_hook)
+			btv->audio_hook(btv,&v,0);
 
 		if(copy_to_user(arg,&v,sizeof(v)))
 			return -EFAULT;
@@ -1902,8 +1863,8 @@
 		bttv_call_i2c_clients(btv,cmd,&v);
 		
 		/* card specific hooks */
-		if (bttv_tvcards[btv->type].audio_hook)
-			bttv_tvcards[btv->type].audio_hook(btv,&v,1);
+		if (btv->audio_hook)
+			btv->audio_hook(btv,&v,1);
 
 		btv->audio_dev=v;
 		up(&btv->lock);
@@ -2483,27 +2444,22 @@
 		bt848_dma(btv, 0);
 }
 
-# define do_video_register(dev,type,nr) video_register_device(dev,type,nr)
-
 static int __devinit init_video_dev(struct bttv *btv)
 {
 	audio(btv, AUDIO_MUTE);
         
-	if(do_video_register(&btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
+	if (video_register_device(&btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
 		return -1;
 	printk(KERN_INFO "bttv%d: registered device video%d\n",
 	       btv->nr,btv->video_dev.minor & 0x1f);
-	if(do_video_register(&btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) 
-        {
+	if (video_register_device(&btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) {
 	        video_unregister_device(&btv->video_dev);
 		return -1;
 	}
 	printk(KERN_INFO "bttv%d: registered device vbi%d\n",
 	       btv->nr,btv->vbi_dev.minor & 0x1f);
-	if (btv->has_radio)
-	{
-		if(do_video_register(&btv->radio_dev, VFL_TYPE_RADIO, radio_nr)<0) 
-                {
+	if (btv->has_radio) {
+		if(video_register_device(&btv->radio_dev, VFL_TYPE_RADIO, radio_nr)<0) {
 		        video_unregister_device(&btv->vbi_dev);
 		        video_unregister_device(&btv->video_dev);
 			return -1;
@@ -2524,13 +2480,14 @@
 
 	/* dump current state of the gpio registers before changing them,
 	 * might help to make a new card work */
-	if (bttv_gpio)
+	if (bttv_gpio) {
+		bttv_gpio_tracking(btv,"init #1");
 		bttv_gpio_tracking(btv,"init #1");
+	}
 
 	/* reset the bt848 */
 	btwrite(0, BT848_SRESET);
-	DEBUG(printk(KERN_DEBUG "bttv%d: bt848_mem: 0x%lx\n", btv->nr, (unsigned long) btv->bt848_mem));
-
+	
 	/* not registered yet */
 	btv->video_dev.minor = -1;
 	btv->radio_dev.minor = -1;
@@ -2973,12 +2930,17 @@
         else
                 btv->i2c_command=(I2C_TIMING | BT848_I2C_SCL | BT848_I2C_SDA);
 
+	if (-1 != latency) {
+		printk(KERN_INFO "bttv%d: setting pci latency timer to %d\n",
+		       bttv_num,latency);
+		pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
+	}
         pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
         pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
         printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %02x:%02x.%x, ",
                bttv_num,btv->id, btv->revision, dev->bus->number,
 	       PCI_SLOT(dev->devfn),PCI_FUNC(dev->devfn));
-        printk("irq: %d, latency: %d, memory: 0x%lx\n",
+        printk("irq: %d, latency: %d, mmio: 0x%lx\n",
 	       btv->dev->irq, lat, btv->bt848_adr);
 	
 	bttv_idcard(btv);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)