[media] saa7164: collect/show the firmware debugging via a thread
authorSteven Toth <stoth@kernellabs.com>
Sat, 31 Jul 2010 19:17:51 +0000 (16:17 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 21 Oct 2010 09:55:12 +0000 (07:55 -0200)
Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/saa7164/saa7164-api.c
drivers/media/video/saa7164/saa7164-core.c
drivers/media/video/saa7164/saa7164.h

index 01cf4ab13b0ff747d76bd3e5bafa9d67865bc353..cf8337dd7bdf747535e53f62f0c9fa88740c72c2 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "saa7164.h"
 
-int saa7164_api_collect_debug(struct saa7164_dev *dev, struct seq_file *m)
+int saa7164_api_collect_debug(struct saa7164_dev *dev)
 {
        tmComResDebugGetData_t d;
        u8 more = 255;
@@ -45,8 +45,7 @@ int saa7164_api_collect_debug(struct saa7164_dev *dev, struct seq_file *m)
                if (d.dwResult != SAA_OK)
                        break;
 
-               seq_printf(m, "%s", d.ucDebugData);
-
+               printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr, d.ucDebugData);
        }
 
        return 0;
index 9f97785447f476861cb36a7f7bd4477957059316..db4b39cb72ac25ef5b27dfb642db0c2a4a8eb7c6 100644 (file)
@@ -1112,15 +1112,51 @@ static int saa7164_proc_show(struct seq_file *m, void *v)
                dev = list_entry(list, struct saa7164_dev, devlist);
                seq_printf(m, "%s = %p\n", dev->name, dev);
 
-               if (dev->board != SAA7164_BOARD_UNKNOWN) {
-                       seq_printf(m, "Firmware messages ----->\n");
-                       saa7164_api_collect_debug(dev, m);
-                       seq_printf(m, "<---- Firmware messages\n");
-               }
-
                /* Lock the bus from any other access */
                b = &dev->bus;
                mutex_lock(&b->lock);
+
+               seq_printf(m, " .m_pdwSetWritePos = 0x%x (0x%08x)\n",
+                       b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos));
+
+               seq_printf(m, " .m_pdwSetReadPos  = 0x%x (0x%08x)\n",
+                       b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos));
+
+               seq_printf(m, " .m_pdwGetWritePos = 0x%x (0x%08x)\n",
+                       b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos));
+
+               seq_printf(m, " .m_pdwGetReadPos  = 0x%x (0x%08x)\n",
+                       b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos));
+               c = 0;
+               seq_printf(m, "\n  Set Ring:\n");
+               seq_printf(m, "\n addr  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
+               for (i = 0; i < b->m_dwSizeSetRing; i++) {
+                       if (c == 0)
+                               seq_printf(m, " %04x:", i);
+
+                       seq_printf(m, " %02x", *(b->m_pdwSetRing + i));
+
+                       if (++c == 16) {
+                               seq_printf(m, "\n");
+                               c = 0;
+                       }
+               }
+
+               c = 0;
+               seq_printf(m, "\n  Get Ring:\n");
+               seq_printf(m, "\n addr  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
+               for (i = 0; i < b->m_dwSizeGetRing; i++) {
+                       if (c == 0)
+                               seq_printf(m, " %04x:", i);
+
+                       seq_printf(m, " %02x", *(b->m_pdwGetRing + i));
+
+                       if (++c == 16) {
+                               seq_printf(m, "\n");
+                               c = 0;
+                       }
+               }
+
                mutex_unlock(&b->lock);
 
        }
@@ -1152,6 +1188,31 @@ static int saa7164_proc_create(void)
 }
 #endif
 
+static int saa7164_thread_function(void *data)
+{
+       struct saa7164_dev *dev = data;
+
+       dprintk(DBGLVL_THR, "thread started\n");
+
+       set_freezable();
+
+       while (1) {
+               msleep_interruptible(100);
+               if (kthread_should_stop())
+                       break;
+               try_to_freeze();
+
+               dprintk(DBGLVL_THR, "thread running\n");
+
+               /* Dump the firmware debug message to console */
+               saa7164_api_collect_debug(dev);
+
+       }
+
+       dprintk(DBGLVL_THR, "thread exiting\n");
+       return 0;
+}
+
 static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
                                     const struct pci_device_id *pci_id)
 {
@@ -1313,6 +1374,14 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
                }
                saa7164_api_set_debug(dev, fw_debug);
 
+               if (fw_debug) {
+                       dev->kthread = kthread_run(saa7164_thread_function, dev,
+                               "saa7164 debug");
+                       if (!dev->kthread)
+                               printk(KERN_ERR "%s() Failed to create "
+                                       "debug kernel thread\n", __func__);
+               }
+
        } /* != BOARD_UNKNOWN */
        else
                printk(KERN_ERR "%s() Unsupported board detected, "
@@ -1340,8 +1409,13 @@ static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
 {
        struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
 
-       if (dev->board != SAA7164_BOARD_UNKNOWN)
+       if (dev->board != SAA7164_BOARD_UNKNOWN) {
+               if (fw_debug && dev->kthread) {
+                       kthread_stop(dev->kthread);
+                       dev->kthread = NULL;
+               }
                saa7164_api_set_debug(dev, 0x00);
+       }
 
        saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
                &dev->ports[ SAA7164_PORT_ENC1 ].irq_interval);
index e2de805c30c15e685315d2e3c8e47e2dad273f6c..88b9b91bf4f5185d66f8cec0be83e013e9f468f9 100644 (file)
@@ -51,6 +51,8 @@
 #include <linux/version.h>
 #include <linux/mutex.h>
 #include <linux/crc32.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
 
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #define DBGLVL_BUF 512
 #define DBGLVL_ENC 1024
 #define DBGLVL_VBI 2048
+#define DBGLVL_THR 4096
 
 #define SAA7164_NORMS ( V4L2_STD_NTSC_M |  V4L2_STD_NTSC_M_JP |  V4L2_STD_NTSC_443 )
 
@@ -471,6 +474,11 @@ struct saa7164_dev {
        /* Deferred command/api interrupts handling */
        struct work_struct workcmd;
 
+       /* A kernel thread to monitor the firmware log, used
+        * only in debug mode.
+        */
+       struct task_struct *kthread;
+
 };
 
 extern struct list_head saa7164_devlist;
@@ -542,7 +550,7 @@ int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect);
 int saa7164_api_get_videomux(struct saa7164_port *port);
 int saa7164_api_set_vbi_format(struct saa7164_port *port);
 int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level);
-int saa7164_api_collect_debug(struct saa7164_dev *dev, struct seq_file *m);
+int saa7164_api_collect_debug(struct saa7164_dev *dev);
 
 /* ----------------------------------------------------------- */
 /* saa7164-cards.c                                             */