Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Oct 2008 10:27:17 +0100
From:      "Martin Laabs" <martin.laabs@mailbox.tu-dresden.de>
To:        "freebsd-emulation@freebsd.org" <freebsd-emulation@freebsd.org>
Subject:   Re: linux-libusb done
Message-ID:  <op.ujoe7rcd724k7f@localhost>
In-Reply-To: <20081026105252.GA45809@freebsd.org>
References:  <op.ujmobziu724k7f@localhost> <20081026105252.GA45809@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Hi,

On Sun, 26 Oct 2008 11:52:52 +0100, Roman Divacky <rdivacky@freebsd.org> wrote:

> please show us the linuxulator patch and I'll see what I can do about it...

I've append the patch for the linux.ko module as well as the patch for the
bsd.c in libusb-0.12.

Greetings,
 Martin
[-- Attachment #2 --]
diff -Naur linux/linux_ioctl.c linux.usb/linux_ioctl.c
--- linux/linux_ioctl.c	2007-11-15 11:38:06.000000000 +0100
+++ linux.usb/linux_ioctl.c	2008-10-26 11:49:59.000000000 +0100
@@ -88,6 +88,8 @@
 static linux_ioctl_function_t linux_ioctl_drm;
 static linux_ioctl_function_t linux_ioctl_sg;
 static linux_ioctl_function_t linux_ioctl_special;
+//for hacked libusb
+static linux_ioctl_function_t linux_ioctl_usb;
 
 static struct linux_ioctl_handler cdrom_handler =
 { linux_ioctl_cdrom, LINUX_IOCTL_CDROM_MIN, LINUX_IOCTL_CDROM_MAX };
@@ -111,6 +113,9 @@
 { linux_ioctl_drm, LINUX_IOCTL_DRM_MIN, LINUX_IOCTL_DRM_MAX };
 static struct linux_ioctl_handler sg_handler =
 { linux_ioctl_sg, LINUX_IOCTL_SG_MIN, LINUX_IOCTL_SG_MAX };
+//USB libusb compatibility mode ...
+static struct linux_ioctl_handler usb_handler =
+{ linux_ioctl_usb, LINUX_IOCTL_USB_MIN, LINUX_IOCTL_USB_MAX };
 
 DATA_SET(linux_ioctl_handler_set, cdrom_handler);
 DATA_SET(linux_ioctl_handler_set, vfat_handler);
@@ -123,6 +128,7 @@
 DATA_SET(linux_ioctl_handler_set, private_handler);
 DATA_SET(linux_ioctl_handler_set, drm_handler);
 DATA_SET(linux_ioctl_handler_set, sg_handler);
+DATA_SET(linux_ioctl_handler_set, usb_handler);                                  
 
 struct handler_element
 {
@@ -2542,6 +2548,60 @@
 	return ioctl(td, (struct ioctl_args *)args);
 }
 
+static int                                                                      
+linux_ioctl_usb(struct thread *td, struct linux_ioctl_args *args)
+{
+       struct file *fp;
+       int error;
+
+       if ((error = fget(td, args->fd, &fp)) != 0)
+           return (error);
+
+#ifdef DEBUG
+       printf("%s(): USB-ioctl %d\n", __func__,
+                  args->cmd & 0xffff);
+#endif
+
+	switch (args->cmd & 0xffff) {
+	case LINUXBSD_IOCTL_USB_DEVICEINFO:
+	  error = ioctl(td, (struct ioctl_args *)args);
+	  break;
+	case LINUXBSD_IOCTL_SET_CONFIG:
+          error = ioctl(td, (struct ioctl_args *)args);
+            break;
+	case LINUXBSD_IOCTL_SET_ALTINTERFACE:
+          error = ioctl(td, (struct ioctl_args *)args);
+            break;
+	case LINUXBSD_IOCTL_SET_TIMEOUT:
+          error = ioctl(td, (struct ioctl_args *)args);
+            break;
+	case LINUXBSD_IOCTL_SET_SHORT_XFER:
+          error = ioctl(td, (struct ioctl_args *)args);
+            break;
+	case LINUXBSD_IOCTL_DO_REQUEST:
+          error = ioctl(td, (struct ioctl_args *)args);
+            break;
+	case LINUXBSD_IOCTL_GET_DEVICE_DESC:
+          error = ioctl(td, (struct ioctl_args *)args);
+            break;
+
+	default:                                                                
+            /* XXX */                                                       
+            linux_msg(td,                                                   
+            "usb ioctl fd=%d, cmd=0x%x ('%c',%d) is not implemented",
+            args->fd, (int)(args->cmd & 0xffff),
+            (int)(args->cmd & 0xff00) >> 8,
+            (int)(args->cmd & 0xff));
+	    error=ENOIOCTL;
+            break;
+	}
+	fdrop(fp, td);
+#ifdef DEBUG
+printf("%s(): USB returning %d\n", __func__, error);
+#endif
+        return (error);
+}
+
 static int
 linux_ioctl_sg(struct thread *td, struct linux_ioctl_args *args)
 {
diff -Naur linux/linux_ioctl.h linux.usb/linux_ioctl.h
--- linux/linux_ioctl.h	2007-11-15 11:38:06.000000000 +0100
+++ linux.usb/linux_ioctl.h	2008-10-25 14:16:13.000000000 +0200
@@ -171,6 +171,15 @@
 #define	LINUX_IOCTL_VFAT_MIN	LINUX_VFAT_READDIR_BOTH
 #define	LINUX_IOCTL_VFAT_MAX	LINUX_VFAT_READDIR_BOTH
 
+
+/*
+ * USB libusb compatibility mode ...
+ */
+ 
+#define LINUX_IOCTL_USB_MIN	0x5503
+#define LINUX_IOCTL_USB_MAX	0x5573
+ 
+ 
 /*
  * console
  */
@@ -567,6 +576,14 @@
 #define	LINUX_IOCTL_DRM_MIN	0x6400
 #define	LINUX_IOCTL_DRM_MAX	0x64ff
 
+#define LINUXBSD_IOCTL_USB_DEVICEINFO	0x5504
+#define LINUXBSD_IOCTL_SET_CONFIG 0x5565
+#define LINUXBSD_IOCTL_SET_ALTINTERFACE 0x5567
+#define LINUXBSD_IOCTL_SET_TIMEOUT 0x5572
+#define LINUXBSD_IOCTL_SET_SHORT_XFER 0x5571
+#define LINUXBSD_IOCTL_DO_REQUEST 0x556f
+#define LINUXBSD_IOCTL_GET_DEVICE_DESC 0x5569
+
 /*
  * This doesn't really belong here, but I can't think of a better
  * place to put it.


[-- Attachment #3 --]
--- bsd.c	2006-03-04 03:52:46.000000000 +0100
+++ libusb-0.1.12-bsd2/bsd.c	2008-10-25 12:14:46.000000000 +0200
@@ -39,7 +39,7 @@
 #include <sys/time.h>
 #include <sys/ioctl.h>
 
-#include <dev/usb/usb.h>
+//#include <dev/usb/usb.h>
 
 #include "usbi.h"
 #ifdef HAVE_CONFIG_H
@@ -131,6 +131,8 @@
 /* This records the file descriptors for the endpoints.  It doesn't seem
    to work to re-open them for each read (as well as being inefficient). */
 
+#define USB_MAX_ENDPOINTS 16                                                    
+
 struct bsd_usb_dev_handle_info {
     int ep_fd[USB_MAX_ENDPOINTS];
 };
@@ -199,8 +201,10 @@
 {
   int ret;
 
-  ret = ioctl(dev->fd, USB_SET_CONFIG, &configuration);
-  if (ret < 0)
+  //ret = ioctl(dev->fd, USB_SET_CONFIG, &configuration);
+ ret = ioctl(dev->fd, ((unsigned long)(0x80000000 | ((sizeof(int) & 0x1fff) << 16) | ((('U')) << 8) | ((101)))), &configuration);
+  
+if (ret < 0)
     USB_ERROR_STR(-errno, "could not set config %d: %s", configuration,
                   strerror(errno));
 
@@ -228,6 +232,12 @@
 int usb_set_altinterface(usb_dev_handle *dev, int alternate)
 {
   int ret;
+struct usb_alt_interface {
+ int uai_config_index;
+ int uai_interface_index;
+ int uai_alt_no;
+};
+
   struct usb_alt_interface intf;
 
   if (dev->interface < 0)
@@ -236,7 +246,9 @@
   intf.uai_interface_index = dev->interface;
   intf.uai_alt_no = alternate;
 
-  ret = ioctl(dev->fd, USB_SET_ALTINTERFACE, &intf);
+  //ret = ioctl(dev->fd, USB_SET_ALTINTERFACE, &intf);
+ ret = ioctl(dev->fd, ((unsigned long)((0x80000000|0x40000000) | ((sizeof(struct usb_alt_interface) & 0x1fff) << 16) | ((('U')) << 8) | ((103)))), &intf);
+
   if (ret < 0)
     USB_ERROR_STR(-errno, "could not set alt intf %d/%d: %s",
                   dev->interface, alternate, strerror(errno));
@@ -256,7 +268,10 @@
    * the mode against the direction; but we've done that
    * already in the usb_bulk_read/write.
    */
-  ep = UE_GET_ADDR(ep);
+
+  ep = ((ep) & 0x0f);
+
+  //ep = UE_GET_ADDR(ep);
 
   if (info->ep_fd[ep] < 0) {
 #ifdef __FreeBSD_kernel__
@@ -293,13 +308,16 @@
 #ifdef __FreeBSD_kernel__
       fprintf (stderr, "usb_bulk_write: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep));
 #else
+#define UE_ADDR         0x0f                                                    
+#define UE_GET_ADDR(a)  ((a) & UE_ADDR)                   
       fprintf (stderr, "usb_bulk_write: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep));
 #endif
     }
     return fd;
   }
+ ret = ioctl(fd, ((unsigned long)(0x80000000 | ((sizeof(int) & 0x1fff) << 16) | ((('U')) << 8) | ((114)))), &timeout);
 
-  ret = ioctl(fd, USB_SET_TIMEOUT, &timeout);
+  //ret = ioctl(fd, USB_SET_TIMEOUT, &timeout);
   if (ret < 0)
     USB_ERROR_STR(-errno, "error setting timeout: %s",
                   strerror(errno));
@@ -337,11 +355,16 @@
     return fd;
   }
 
-  ret = ioctl(fd, USB_SET_TIMEOUT, &timeout);
+ // ret = ioctl(fd, USB_SET_TIMEOUT, &timeout);
+ ret = ioctl(fd, ((unsigned long)(0x80000000 | ((sizeof(int) & 0x1fff) << 16) | ((('U')) << 8) | ((114)))), &timeout);
+  if (ret < 0)
+
   if (ret < 0)
     USB_ERROR_STR(-errno, "error setting timeout: %s", strerror(errno));
 
-  ret = ioctl(fd, USB_SET_SHORT_XFER, &one);
+//  ret = ioctl(fd, USB_SET_SHORT_XFER, &one);
+ ret = ioctl(fd, ((unsigned long)(0x80000000 | ((sizeof(int) & 0x1fff) << 16) | ((('U')) << 8) | ((113)))), &one);
+
   if (ret < 0)
     USB_ERROR_STR(-errno, "error setting short xfer: %s", strerror(errno));
 
@@ -378,7 +401,9 @@
     return fd;
   }
 
-  ret = ioctl(fd, USB_SET_TIMEOUT, &timeout);
+//  ret = ioctl(fd, USB_SET_TIMEOUT, &timeout);
+  ret = ioctl(fd, ((unsigned long)(0x80000000 | ((sizeof(int) & 0x1fff) << 16) | ((('U')) << 8) | ((114)))), &timeout);
+
   if (ret < 0)
     USB_ERROR_STR(-errno, "error setting timeout: %s",
                   strerror(errno));
@@ -420,11 +445,16 @@
     return fd;
   }
 
-  ret = ioctl(fd, USB_SET_TIMEOUT, &timeout);
+  //ret = ioctl(fd, USB_SET_TIMEOUT, &timeout);
+ ret = ioctl(fd, ((unsigned long)(0x80000000 | ((sizeof(int) & 0x1fff) << 16) | ((('U')) << 8) | ((114)))), &timeout);
+  if (ret < 0)
+
   if (ret < 0)
     USB_ERROR_STR(-errno, "error setting timeout: %s", strerror(errno));
 
-  ret = ioctl(fd, USB_SET_SHORT_XFER, &one);
+//  ret = ioctl(fd, USB_SET_SHORT_XFER, &one);
+ ret = ioctl(fd, ((unsigned long)(0x80000000 | ((sizeof(int) & 0x1fff) << 16) | ((('U')) << 8) | ((113)))), &one);
+
   if (ret < 0)
     USB_ERROR_STR(-errno, "error setting short xfer: %s", strerror(errno));
 
@@ -447,7 +477,34 @@
 int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
                      int value, int index, char *bytes, int size, int timeout)
 {
-  struct usb_ctl_request req;
+
+#define UPACKED __packed                                                        
+
+typedef u_int8_t uByte;
+typedef u_int8_t uWord[2];                                                      
+typedef u_int8_t uDWord[4];       
+ 
+typedef struct {
+ uByte bmRequestType;
+ uByte bRequest;
+ uWord wValue;
+ uWord wIndex;
+ uWord wLength;
+} __attribute__((__packed__)) usb_device_request_t;
+
+
+struct usb_ctl_request {
+ int ucr_addr;
+ usb_device_request_t ucr_request;
+ void *ucr_data;
+ int ucr_flags;
+
+ int ucr_actlen;
+};
+
+
+
+struct usb_ctl_request req;
   int ret;
 
   if (usb_debug >= 3)
@@ -456,14 +513,23 @@
 
   req.ucr_request.bmRequestType = requesttype;
   req.ucr_request.bRequest = request;
-  USETW(req.ucr_request.wValue, value);
-  USETW(req.ucr_request.wIndex, index);
-  USETW(req.ucr_request.wLength, size);
+//  USETW(req.ucr_request.wValue, value);
+//  USETW(req.ucr_request.wIndex, index);
+//  USETW(req.ucr_request.wLength, size);
+
+    ((req.ucr_request.wValue)[0] = (u_int8_t)(value), (req.ucr_request.wValue)[1] = (u_int8_t)((value) >> 8));
+  ((req.ucr_request.wIndex)[0] = (u_int8_t)(index), (req.ucr_request.wIndex)[1] = (u_int8_t)((index) >> 8));
+  ((req.ucr_request.wLength)[0] = (u_int8_t)(size), (req.ucr_request.wLength)[1] = (u_int8_t)((size) >> 8));
 
+  
   req.ucr_data = bytes;
-  req.ucr_flags = USBD_SHORT_XFER_OK;
+//  req.ucr_flags = USBD_SHORT_XFER_OK;
+  req.ucr_flags = 0x04;
+
+
+//  ret = ioctl(dev->fd, USB_SET_TIMEOUT, &timeout);
+  ret = ioctl(dev->fd, ((unsigned long)(0x80000000 | ((sizeof(int) & 0x1fff) << 16) | ((('U')) << 8) | ((114)))), &timeout);
 
-  ret = ioctl(dev->fd, USB_SET_TIMEOUT, &timeout);
 #if (__NetBSD__ || __OpenBSD__)
   if (ret < 0 && errno != EINVAL)
 #else
@@ -472,12 +538,16 @@
     USB_ERROR_STR(-errno, "error setting timeout: %s",
                   strerror(errno));
 
-  ret = ioctl(dev->fd, USB_DO_REQUEST, &req);
+//  ret = ioctl(dev->fd, USB_DO_REQUEST, &req);
+ ret = ioctl(dev->fd, ((unsigned long)((0x80000000|0x40000000) | ((sizeof(struct usb_ctl_request) & 0x1fff) << 16) | ((('U')) << 8) | ((111)))), &req);
+
   if (ret < 0)
     USB_ERROR_STR(-errno, "error sending control message: %s",
                   strerror(errno));
 
-  return UGETW(req.ucr_request.wLength);
+//  return UGETW(req.ucr_request.wLength);
+  return ((req.ucr_request.wLength)[0] | ((req.ucr_request.wLength)[1] << 8));
+
 }
 
 int usb_os_find_busses(struct usb_bus **busses)
@@ -526,22 +596,66 @@
   struct usb_device *fdev = NULL;
   int cfd, dfd;
   int device;
-
-  cfd = open(bus->dirname, O_RDONLY);
+ 
+  fprintf(stderr, "usb_os_find_devices: Hello\n"
+              );
+ 
+cfd = open(bus->dirname, O_RDONLY);
   if (cfd < 0)
     USB_ERROR_STR(-errno, "couldn't open(%s): %s", bus->dirname,
                   strerror(errno));
+#define USB_MAX_DEVICES 128                                                     
+
 
   for (device = 1; device < USB_MAX_DEVICES; device++) {
+
+typedef struct { u_int32_t cookie; } usb_event_cookie_t;
+
+struct usb_device_info {
+ u_int8_t udi_bus;
+ u_int8_t udi_addr;
+ usb_event_cookie_t udi_cookie;
+ char udi_product[128];
+ char udi_vendor[128];
+ char udi_release[8];
+ u_int16_t udi_productNo;
+ u_int16_t udi_vendorNo;
+ u_int16_t udi_releaseNo;
+ u_int8_t udi_class;
+ u_int8_t udi_subclass;
+ u_int8_t udi_protocol;
+ u_int8_t udi_config;
+ u_int8_t udi_speed;
+
+
+
+ int udi_power;
+ int udi_nports;
+ char udi_devnames[4][16];
+ u_int8_t udi_ports[16];
+
+
+
+
+};
+
+
     struct usb_device_info di;
     struct usb_device *dev;
-    unsigned char device_desc[DEVICE_DESC_LENGTH];
+    unsigned char device_desc[18];
+
+//  unsigned char device_desc[DEVICE_DESC_LENGTH];
     char buf[20];
 
     di.udi_addr = device;
-    if (ioctl(cfd, USB_DEVICEINFO, &di) < 0)
+//    if (ioctl(cfd, USB_DEVICEINFO, &di) < 0)
+  if (ioctl(cfd, ((unsigned long)((0x80000000|0x40000000) | ((sizeof(struct usb_device_info) & 0x1fff) << 16) | ((('U')) << 8) | ((4)))), &di) < 0)
       continue;
 
+   fprintf(stderr, "usb_os_find_devices: cfd: %d\n",
+              cfd);
+
+
     /* There's a device; is it one we should mess with? */
 
     if (strncmp(di.udi_devnames[0], "ugen", 4) != 0)
@@ -580,8 +694,34 @@
 
     strncpy(dev->filename, buf, sizeof(dev->filename) - 1);
     dev->filename[sizeof(dev->filename) - 1] = 0;
+typedef u_int8_t uByte;
+typedef u_int8_t uWord[2];
+typedef u_int8_t uDWord[4];
+
+
+typedef struct {
+ uByte bLength;
+ uByte bDescriptorType;
+ uWord bcdUSB;
+
+
+ uByte bDeviceClass;
+ uByte bDeviceSubClass;
+ uByte bDeviceProtocol;
+ uByte bMaxPacketSize;
+
+ uWord idVendor;
+ uWord idProduct;
+ uWord bcdDevice;
+ uByte iManufacturer;
+ uByte iProduct;
+ uByte iSerialNumber;
+ uByte bNumConfigurations;
+} __attribute__((__packed__)) usb_device_descriptor_t;
+
+//  if (ioctl(dfd, USB_GET_DEVICE_DESC, device_desc) < 0)
+  if (ioctl(dfd, ((unsigned long)(0x40000000 | ((sizeof(usb_device_descriptor_t) & 0x1fff) << 16) | ((('U')) << 8) | ((105)))), device_desc) < 0)
 
-    if (ioctl(dfd, USB_GET_DEVICE_DESC, device_desc) < 0)
       USB_ERROR_STR(-errno, "couldn't get device descriptor for %s: %s",
                     buf, strerror(errno));
 

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?op.ujoe7rcd724k7f>