Todd T. Fries wrote:
For the archive, this is what he is wanting to do, or something very similar..

Yes, thank you!  That is exactly what I need.

My only problem now is that ioctl always returns -1. My OpenBSD test system doesn't seem to be new enough.
$ uname -a
OpenBSD bsd.pjrc.com 4.6 GENERIC#58 i386

I'm downloading "install46.iso" from the snaphot directory now.....


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <err.h>
#include <errno.h>
#include <dev/usb/usb.h>

#define VID             0x16C0
#define PID             0x0478

int open_my_usb_device(int vid, int pid);

int
main(int argc, char **argv)
{
        return open_my_usb_device(VID, PID);
}


#define UHIDEV          "/dev/uhid"

int open_my_usb_device(int vid, int pid)
{
        struct usb_device_info  di;
        const char *dev_name;
        char buf[50];
        int f,e,i,n;

        for (n = 0, i = 0; i < 10; i++) {
                snprintf(buf, sizeof buf, "%s%d", UHIDEV, i);
                f = open(buf, O_RDWR);
                if (f < 0)
                        continue;

                e = ioctl(f, USB_GET_DEVICEINFO, &di);
                if (e) {
                        close(f);
                        continue;
                }
                if (di.udi_vendorNo == vid && di.udi_productNo == pid)
                        printf("found one: ");

                printf("%s: %s(0x%04x), %s(0x%04x), rev %s\n",
                        buf, di.udi_product, di.udi_productNo,
                        di.udi_vendor, di.udi_vendorNo, di.udi_release);
                n++;
                break;
        }
        if (n == 0)
                printf("no uhid found\n");

        return f;
}


Penned by Paul Stoffregen on 20100121 12:50.58, we have:
| I'm hoping this is the right list for this question, and please
| forgive me if this is a dumb question or it's been asked before.
| I've tried google and man pages and about a day's worth of coding
| with little success.
| | I'm trying to support OpenBSD in a new version of this program
| http://www.pjrc.com/teensy/loader_cli.html  Based on an earlier
| patch from Chris Kuethe, it's working great on OpenBSD.  Well,
| except the /dev/uhid0 device name is hard-coded, and my next version
| will have a feature to use multiple devices at the same time (for
| different functions, based on their product IDs), so hard coding or
| expecting the user to supply the device names just isn't practical.
| | My question: how do I figure out which /dev/uhid device file(s), if
| any, corresponds to my device's product and vendor ID numbers?
| Basically, this is what I need to do:
| | int open_my_usb_device(int vid, int pid)
| {
|        const char *dev_name;
| | // TODO: Perform some magic to figure out
|        // which /dev/uhid# device is actually the
|        // this vendor and product ID.
| | dev_name = "/dev/uhid0"; // not hard coded like this, nor
| from user input
| | return open(dev_name, O_RDWR);
| }
| | I've tried opening the /dev/usb devices and calling the
| USB_DEVICEINFO ioctl (originally suggested to me by Todd T Fries).
| This gets very close, but the best I've been able to do is learn
| which uhidev driver (but not uhid) is connected to my device.  For
| example (this code copied at the end of this email):
| | $ ./test /dev/usb1
| addr 1: 0x0000, 0x106b, rev 1.00, drivers:  uhub1
| addr 2: 0x0478, 0x16c0, rev 1.20, drivers:  uhidev0
| | This tells me the uhidev0 driver is loaded for my device. But the
| mapping from uhidev to uhid isn't necessarily 1-to-1.  I need to
| know which uhid device to open!
| | So far, the only way I've discovered to learn which uhid device
| corresponds to my hardware is by looking at /var/log/messages.
| | $ tail -3 /var/log/messages Jan 21 00:42:11 bsd /bsd: uhidev0 at
| uhub1 port 1 configuration 1 interface 0 "vendor 0x16c0 product
| 0x0478" rev 1.10/1.20 addr 2
| Jan 21 00:42:11 bsd /bsd: uhidev0: iclass 3/0
| Jan 21 00:42:11 bsd /bsd: uhid0 at uhidev0: input=0, output=130, feature=0
| | I suppose I could write code to try parsing /var/log/messages, but
| that seems like a horribly ugly hack that's bound to fail at some
| point in the future.
| | | Here is the work in progress. | | http://www.pjrc.com/tmp/teensy_loader_cli.work-in-progress.zip | | I've finished Linux, Windows and Macos support, and BSD is working
| but the device name is hard coded.  I'm truly stuck on this last
| bit, so I'm hoping you might tell me how I can figure out how to
| find the right uhid device for my product/vendor IDs.  This is the
| last piece I need to support BSD as well as the other systems.
| | | Thanks, | | -Paul
| [email protected]
| | | // test.c
| #include <stdio.h>
| #include <string.h>
| #include <fcntl.h>
| #include <unistd.h>
| #include <err.h>
| #include <dev/usb/usb.h>
| // originally suggested by Todd T. Fries
| | int
| main(int argc, char **argv)
| {
|        struct usb_device_info   di;
|        int                      i, e,f,a;
| | f = open(argv[1], O_RDWR);
|        if (f < 0) err(1, "%s", argv[1]);
| | for (a=0; a < USB_MAX_DEVICES; a++) {
|                memset(&di, 0, sizeof(struct usb_device_info));
|                di.udi_addr = a;
|                e = ioctl(f, USB_DEVICEINFO, &di);
|                if (e) continue;
|                printf("addr %d: 0x%04x, 0x%04x, rev %s, drivers: ", a,
|                        di.udi_productNo, di.udi_vendorNo, di.udi_release);
|                for (i=0; i < USB_MAX_DEVNAMES; i++) {
|                        if (*di.udi_devnames[i] == NULL) continue;
|                        printf(" %s", di.udi_devnames[i]);
|                }
|                printf("\n");
|        }
|        close(f);
|        return 0;
| }

Reply via email to