pvrusb2 driver debug interface usage

$Id: dbgifc.html 1875 2008-02-09 00:26:43Z isely $

Mike Isely <isely at pobox dot com>

You can find the main driver page on the web at http://www.isely.net/pvrusb2/pvrusb2.html.

This page provides additional information related to operation of the driver's debug interface. You don't need to worry about this information unless you're actually trying to debug a problem. (This interface is also used for part of the manual firmware extraction process however in that case, the instructions for that process include the debug interface information you would need.)


Contents

Overview
Debug Interface Basics
Debug Interface Available Commands

Overview

The pvrusb2 driver includes a debug interface, which is a method for inspecting driver information and injecting actions into the driver. The interface is command line-based; i.e. you feed the driver a string containing a command and read back results.

Given that we're talking about a Linux kernel mode driver and not some kind of userspace application, then how is it possible to even have a command interface? It's just another sysfs trick. Commands are issued by echoing the string into a particular sysfs file. Reading that same file back returns status information. It's that simple.


Debug Interface Basics

First, you need to ensure that the debug interface has been compiled into the driver. Since this interface isn't needed for normal driver operation, then it's likely that a distribution's precompiled kernel with this driver might not have it on. If that is the case for you, then you'll have to rebuild the driver with the appropriate CONFIG option set. Sorry, but that's unavoidable.

The CONFIG option that needs to be on is "CONFIG_VIDEO_PVRUSB2_DEBUGIFC"; it is described as "pvrusb2 debug interface" as an option related to selecting the pvrusb2 driver itself.

If you are using a standalone snapshot of the driver (i.e. you downloaded a tarball from the pvrusb2 web site), then the build process normally always turns on this option for you. In that case, you can ignore the previous two paragraphs.

To access the debug interface, plug in your device as usual, open a shell prompt, then change directory to the driver's sysfs directory. The directory you want will be of the pattern "/sys/class/pvrusb2/sn-XXXXXXXX". (General information about the sysfs interface can be found here.) List that directory and you should find two entries of interest, one named "debugcmd" and the other named "debuginfo". If they aren't present, then odds are that the debug interface has not been compiled into the driver - see above for information on fixing that problem.

The "debugcmd" file is how commands are issued; anything written to here will be parsed and acted upon by the pvrusb2 driver.

You can read from either of "debugcmd" or "debuginfo" to retrieve debugging information from the driver. Different information is produced in each case.

Generally, reading from debugcmd returns information more directly related to specific low level debugging and only really has meaning in the context of other debug commands. Information printed from debugcmd will include a report of USB link speed, GPIO states, and an indication if streaming should be in progress or not.

Reading from "debuginfo" produces information about the driver as a whole - and the mere act of reading this file also triggers a dump of more information into the system log. You'll get 3 categories of information here:

A lot can be learned about what is going on simply by reading "debuginfo" and also examining the system log afterwards.

To make this a little more clear, let's consider an example. Suppose you wanted to force the FX2 processor to reset. The command in that case would be:

echo "reset cpu" >debugcmd

That then causes the driver to issue USB control transfers that ultimately force the FX2 to reset. (However you probably don't want to do this just for kicks, as it will cause the device to momentarily disconnect its USB interface which will look to the kernel like you unplugged then replugged in the cable, which will then cause this sysfs instance to be reset as well. But hey, I said this was a debug interface...)

To summarize:


Debug Interface Available Commands

Below is a list of the currently available debug interface commands. Please remember that these commands are for debugging issues and not for normal operation. Many of these actions can potentially leave the driver in an operable state and/or require power cycling of the PVR USB2 hardware.

Various Resets

reset cpu
A CPU reset triggers a direct reset of the FX2 microcontroller within the PVR USB2 device. Doing this will cause the PVR USB2 hardware to temporarily disconnect itself from the USB controller; that will have the effect of causing the entire sysfs interface to momentarily disappear then reinitialize (same action as if you unplugged the hardware then plugged it back in).
reset bus
A bus reset causes the USB-level transaction that resets the bus itself. This reset is specific to the device at the other end of the bus, that being the PVR USB2 device. It should not affect any other connected devices.
reset soft
A soft reset triggers a specific FX2 command that is suspected to reset some internal state. This might not be entirely correct, but the command is here.
reset deep
A "deep" reset triggers a specific FX2 command that is suspected to reset additional internal PVR USB2 hardware. Again, this might be entirely correct, but the command remains mainly due to history.
reset firmware
To reset the "firmware" in this case is actually an action to cause the encoder's firmware to be reloaded. Normally you never need to do this because the driver itself figures out when the encoder needs a reload and will do it on its own.
reset decoder
This issues a reset command to the decoder chip (e.g. the cx25843 or the saa7115) inside the device. Again this sort of action is normally handled automatically.
reset worker
The driver has a soft "error" state it can get into under certain circumstances. At the moment this can happen if it fails to load the encoder firmware. This error state is implemented in an attempt to keep the driver from getting into a tight loop where it might be continuously trying to fruitlessly reload the firmware. Once the state it set, the driver essentially gives up until the state is cleared. Under normal circumstances the driver will automatically clear this state if it thinks there is a reason why it might now succeed where previously it had failed. But you can also manually clear the error state with this command.

Firmware Fetching

The driver implements a mechanism for pulling firmware data back out of the device. This refers to only the FX2 firmware - currently there isn't any known means for retrieving the encoder firmware after it has been loaded. This ability is used as part of the manual firmware extraction process (relevant part described here).

The debug interface itself has no means for actually reading large amounts of data (and sysfs itself really isn't that suitable for such a thing). Because of this, the actual act of slurping out the firmware contents happens through the V4L interface. But it is controlled through the debug interface. This works by first issuing a debug interface command to put the driver into "suck firmware mode", then you can grab the contents with a normal cat command from the /dev node (e.g. "/dev/video0") you would normally use to stream video. Finally another debug interface command is issued to return the driver back to normal mode. The debug interface commands are:

cpufw fetch ram
Put the driver into firmware fetching mode and grab the in-memory contents of the FX2 microcontroller.
cpufw fetch prom
Put the driver into firmware fetching mode and grab the contents of the device's I2C PROM. This may or may not make sense for the particular device. Some devices load their FX2 firmware from a nearby I2C PROM device; others expect to be loaded by the host. In the host-loaded cases the PROM might not have anything useful (it might not even be present).
cpufw done
Undo the effects of either of the cpufw fetch commands and return the driver to normal operation.

So, to use this mechanism one must do:

  1. Issue either "cpufw fetch ram" or "cpufw fetch prom" to the debug interface
  2. Grab the firmware contents, by for example doing: cat /dev/video >tmp/foo.fw
  3. Issue either "cpufw done" to the debug interface

Note that the hardware implementation that makes the "cpufw fetch ram" command possible is somewhat destructive to the device's current state. No permanent harm is done of course, but when the "done" step is performed, the device will reset itself and the driver will re-initialize it. That will also have the effect of causing the driver's sysfs interface to be torn down and recreated (thus affecting this debug interface).

GPIO Manipulation

The encoder chip has the ability to control a set of general purpose I/O (GPIO) signals. Various tuner devices use these signals to affect aspects of the device. For example, Hauppauge tuners use one GPIO to control the LED. Other devices might use a GPIO to switch an analog mux that might control selection of the stereo audio input versus the internal FM tuner. Encoder firmware loading also seems to require manipulation of various GPIO signals. As a Linux driver author, there's a certain amount of guesswork needed to figure this out. So the debug interface here includes the ability to directly access GPIO signals.

In our case, there are 3 GPIO registers of interest: an input register, an output register, and a direction register. Generally (there is one important exception), each bit of each register corresponds to a specific GPIO. For example, bit 11 of each register corresponds to hardware GPIO bit 11. The direction register control the in vs out setting of each bit. Reading the input register reads all the GPIO states, while writing the output register sets the GPIO states (for all GPIOs that are set as outputs).

Setting a bit in the direction register sets the corresponding GPIO as an output bit. There is one exception here for our hardware however: GPIO bits 0 through 7 are treated as a unit in the direction register, controlled by direction register bit 7. Said another way, setting bit 7 in the direction register programs all of GPIO bits 0 through 7 as outputs; cleaing direction register bit 7 programs all of GPIO bits 0 through 7 as inputs. Best I can tell right now is that direction register bits 0 through 6 simply have no effect.

So, suppose you wish to clear GPIO bit 11. To do this, you first must ensure that bit position 11 in the direction register has a 1 in it, then put a 0 in bit position 11 of the output register.

To read current GPIO states, just read debugcmd itself; part of the output includes all GPIO states.

With all that said, here are the debug interface commands to control GPIO signals:

gpio dir <mask> <value>
This command controls the direction register. The <mask> argument specifies which bits you wish to modify in the register. The <value> argument specifies new bit values for those bits that were set in the <mask>.
gpio out <mask> <value>
This command controls the output register. The <mask> argument specifies which bits you wish to modify in the register. The <value> argument specifies new bit values for those bits that were set in the <mask>.

There is no command to control the input register - it is a read-only register and its value is always provided as part of the output when reading the "debugcmd" file itself.

The argument values are expected to be integers. But since they are interpreted as bit mask combinations you will naturally want to use hex values here. Just use the usual C language convention of prefixing 0x to the number and that will have the desired effect.

Given the above and revisiting our example, then to clear GPIO bit 11, the following commands would be issued:

echo "gpio dir 0x0800 0x0800" >debugcmd
echo "gpio out 0x0800 0x0000" >debugcmd