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>
