Re: guppy

14 views
Skip to first unread message

Tony Tsui

unread,
Apr 18, 2009, 5:01:15 AM4/18/09
to M.S.Colclough, gupp...@googlegroups.com
Hi Mark,

On Fri, Apr 17, 2009 at 7:48 PM, M.S.Colclough <m.s.co...@bham.ac.uk> wrote:
Hi,

I tried your guppy Topfield gui the other day, and I think it is very nice work, thanks.

Thanks! :)
 
I have been using puppy at the command line for a long time, and although I had heard that there was a gui, I was afraid it would add complexity, but not so!

I have modified puppy so it will work directly from sysfs (and use the /dev device) instead of the usbfs stuff in /proc.  As I'm sure you know, usbfs is deprecated and is vanishing
from distro defaults (see, e.g.
https://bugs.launchpad.net/ubuntu/+source/sysvinit/+bug/35004
).

Nice patch! Would you mind sending me the patch so I can have a play around with it.
 
The original author seems to have lost interest in the Topfield:
https://www.blogger.com/comment.g?blogID=9369670&postID=6535818317134467179
I emailed and posted to his blog, with no results.

Perhaps you should fork puppy and make a one-stop guppy solution?  I would contribute my patch.  It's straightforward and does not bring in extra libraries.

I've been considering the same idea recently, but haven't had any strong impetus to do so. Sounds like your patch will make it worthwhile.

I hope you don't mind but I've CC-ed the guppy discussion group.

Cheers,
Tony

regards,
Mark Colclough


Tony Tsui

unread,
Apr 18, 2009, 6:02:43 PM4/18/09
to M.S.Colclough, gupp...@googlegroups.com
Hi Mark,

On Sat, Apr 18, 2009 at 1:28 PM, M.S.Colclough <m.s.co...@bham.ac.uk> wrote:
Hi Tony,

Here's the patch for puppy, attached  It just hunts for the device in /sys instead of usbfs (which implies a few more changes).

The patch works great. A nice side effect is that I can get rid of the HAL FDI script for setting the permission of the usbfs file.

I've imported the Puppy source into the Guppy git repo. You can find it here: http://github.com/ttsui/guppy/tree/master. I've also checked in your patch.

I'll include this version of Puppy with the next Guppy release.
 
I an a Zenwalk linux developer, which means that backwards compatibility isn't a concern for me.  Before releasing a package for general use, I'd want to know if there are any interesting distros that don't have /sys/bus/usb/devices/... and /dev/bus/usb/BBB/DDD.  If so, it would be possible to try usbfs as well; but I'd rather not.

I'm not sure if it will be an issue. If it turns out to be an issue we can add usbfs support back in.

Cheers,
Tony

regards
Mark

diff -uNr puppy_1.14.orig/puppy.c puppy_1.14.new/puppy.c
--- puppy_1.14.orig/puppy.c     2008-04-10 06:48:02.000000000 +0100
+++ puppy_1.14.new/puppy.c      2009-04-12 17:07:44.144688127 +0100
@@ -8,6 +8,7 @@
 /*

  Copyright (C) 2004-2008 Peter Urbanec <toppy at urbanec.net>
+  Copyright (C) 2009 Mark Colclough <m.s.colclough bham.ac.uk> (findToppy)

  This file is part of puppy.

@@ -44,6 +45,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <asm/byteorder.h>
+#include <dirent.h>

 #include "usb_io.h"
 #include "tf_bytes.h"
@@ -51,7 +53,9 @@
 #define PUT 0
 #define GET 1

-#define MAX_DEVICES_LINE_SIZE 128
+#define SYSPATH_MAX 256
+#define TOPPYVID 0x11db
+#define TOPPYPID 0x1000

 extern time_t timezone;

@@ -961,8 +965,7 @@
        " -P             - full packet dump output to stderr\n"
        " -q             - quiet transfers - no progress updates\n"
        " -v             - verbose output to stderr\n"
-        " -d <device>    - USB device (must be usbfs)\n"
-        "                  for example /proc/bus/usb/001/003\n"
+        " -d <device>    - USB device, for example /dev/bus/usb/001/003\n"
        " -c <command>   - one of size, dir, get, put, rename, delete, mkdir, reboot, cancel, turbo\n"
        " args           - optional arguments, as required by each command\n\n"
        "Version: " PUPPY_RELEASE ", Compiled: " __DATE__ "\n";
@@ -1142,18 +1145,35 @@

 int isToppy(struct usb_device_descriptor *desc)
 {
-    return (desc->idVendor == 0x11db) && (desc->idProduct == 0x1000);
+    return (desc->idVendor == TOPPYVID) && (desc->idProduct == TOPPYPID);
 }

+/* Read up to valuesize bytes from the file /sys/bus/usb/devices/DEVNAME/ITEM
+ * into the string pointed at by value.  Return 1=OK, 0=error */
+int readsysfs(char* devname, char* item, char *value, int valuesize)
+{
+    char filname[SYSPATH_MAX];
+    FILE *fil;
+
+    snprintf(filname, SYSPATH_MAX, "/sys/bus/usb/devices/%s/%s", devname, item);
+    if (!(fil = fopen(filname, "r"))) return 0;
+    fgets(value, valuesize, fil);
+    fclose(fil);
+    return 1;
+}
+
+/* Find a Topfield PVR on the usb.  Return the device as a static string of the
+ * form /dev/bus/usb/BBB/DDD or NULL if not found or other error. */
 char *findToppy(void)
 {
-    FILE *toppy;
-    char buffer[MAX_DEVICES_LINE_SIZE];
-    int bus, device;
-    unsigned int vendor, prodid;
-    int found = 0;
+    DIR *devicesdir;
+    struct dirent *direntry;
+    char vid[5];
+    char pid[5];
+    char bus[5];
+    char device[5];
    static char pathBuffer[32];
-
+
    /* Refuse to scan while another instance is running. */
    if(0 != flock(lockFd, LOCK_EX | LOCK_NB))
    {
@@ -1161,62 +1181,57 @@
                "ERROR: Can not scan for devices while another instance of puppy is running.\n");
        return NULL;
    }
-
-    /* Open the /proc/bus/usb/devices file, and read it to find candidate Topfield devices. */
-    if((toppy = fopen("/proc/bus/usb/devices", "r")) == NULL)
+
+    pathBuffer[0] = '\0';  /* Signify nothing found at entry */
+
+    /* Iterate over all usb devices, looking for Topfield */
+    if (!(devicesdir = opendir("/sys/bus/usb/devices")))
    {
        fprintf(stderr,
                "ERROR: Can not perform autodetection.\n"
-                "ERROR: /proc/bus/usb/devices can not be open for reading.\n"
+                "ERROR: /sys/bus/usb/devices can not be opened.\n"
                "ERROR: %s\n", strerror(errno));
        return NULL;
    }
-
-    /* Scan the devices file, line by line, looking for Topfield devices. */
-    while(fgets(buffer, MAX_DEVICES_LINE_SIZE, toppy))
+
+    while ((direntry = readdir(devicesdir)))
    {
-
-        /* Store the information from topology lines. */
-        if(sscanf
-           (buffer, "T: Bus=%d Lev=%*d Prnt=%*d Port=%*d Cnt=%*d Dev#=%d",
-            &bus, &device))
-        {
-            trace(2,
-                  fprintf(stderr, "Found USB device at bus=%d, device=%d\n",
-                          bus, device));
-        }
-
-        /* Look for Topfield vendor/product lines, and also check for multiple devices. */
-        else if(sscanf(buffer, "P: Vendor=%x ProdID=%x", &vendor, &prodid)
-                && (vendor == 0x11db) && (prodid == 0x1000))
+        /* Skip non-device entries */
+        if (direntry->d_name[0] == '.'
+            || direntry->d_name[0] == 'u'
+            || strchr(direntry->d_name, ':')) continue;
+
+        /* Skip if not correct vendor and product ID */
+        readsysfs(direntry->d_name, "idVendor", vid, sizeof(vid));
+        readsysfs(direntry->d_name, "idProduct", pid, sizeof(pid));
+        trace(2, fprintf(stderr, "Found USB device bus-port=%s, vid=%s, pid=%s\n",
+                                                direntry->d_name, vid, pid));
+        if (strtol(vid, NULL, 16) != TOPPYVID
+            || strtol(pid, NULL, 16) != TOPPYPID) continue;
+
+        trace(1, fprintf(stderr, "Recognised Topfield device at bus-port=%s\n",
+                                                direntry->d_name));
+
+        /* Error if multiple matching devices found */
+        if (pathBuffer[0])
        {
-            trace(1,
-                  fprintf(stderr,
-                          "Recognised Topfield device at bus=%d, device=%d\n",
-                          bus, device));
-
-            /* If we've already found one, then there are multiple devices present. */
-            if(found)
-            {
-                fprintf(stderr,
-                        "ERROR: Multiple Topfield devices recognised.\n"
-                        "ERROR: Please use the -d option to specify a device.\n");
-                fclose(toppy);
-                return NULL;
-            }
-
-            /* Construct the device path according to the topology found. */
-            sprintf(pathBuffer, "/proc/bus/usb/%03d/%03d", bus, device);
-            found = 1;
-        }
+            fprintf(stderr,
+                    "ERROR: Multiple Topfield devices recognised.\n"
+                    "ERROR: Please use the -d option to specify a device.\n");
+            return NULL;
+        }
+
+        /* Construct the device path for the first matching device */
+        readsysfs(direntry->d_name, "busnum", bus, sizeof(bus));
+        readsysfs(direntry->d_name, "devnum", device, sizeof(device));
+        sprintf(pathBuffer, "/dev/bus/usb/%03d/%03d", atoi(bus), atoi(device));
+
+        /* Continue iterating, to check for multiple matching devices */
    }
-
-    fclose(toppy);
-
-    if(found)
+    if (pathBuffer[0])
    {
        return pathBuffer;
-    }
+    }
    else
    {
        fprintf(stderr, "ERROR: Can not autodetect a Topfield TF5000PVRt\n");


Reply all
Reply to author
Forward
0 new messages