Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Jul 2013 13:44:47 +0200
From:      Hans Petter Selasky <hps@bitfrost.no>
Cc:        "freebsd-usb@freebsd.org" <freebsd-usb@freebsd.org>
Subject:   Re: COMPAT_32BIT libusb ABI problem
Message-ID:  <51F2612F.9010703@bitfrost.no>
In-Reply-To: <zarafa.51f175f9.25d7.1ecfc86c5d6b39b6@mail.lockless.no>
References:  <CAJm2B-mfidBre0tCwJg=6OirBtdgvxCTrGGVX-3kqQ8vYf1kFw@mail.gmail.com> <zarafa.51f175f9.25d7.1ecfc86c5d6b39b6@mail.lockless.no>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------000209000009070500010606
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi Damjan,

Does the attached patch fix the problem for you?

--HPS

--------------000209000009070500010606
Content-Type: text/x-patch;
 name="usb_ioctl32.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="usb_ioctl32.diff"

=== sys/dev/usb/quirk/usb_quirk.c
==================================================================
--- sys/dev/usb/quirk/usb_quirk.c	(revision 253548)
+++ sys/dev/usb/quirk/usb_quirk.c	(local)
@@ -692,8 +692,8 @@
 	uint32_t y;
 	int err;
 
-	switch (cmd) {
-	case USB_DEV_QUIRK_GET:
+	switch (USB_IOCTL_SWAP(cmd)) {
+	case USB_IOCTL_RANGE(USB_DEV_QUIRK_GET):
 		pgq = (void *)data;
 		x = pgq->index % USB_SUB_QUIRKS_MAX;
 		y = pgq->index / USB_SUB_QUIRKS_MAX;
@@ -712,7 +712,7 @@
 		mtx_unlock(&usb_quirk_mtx);
 		return (0);		/* success */
 
-	case USB_QUIRK_NAME_GET:
+	case USB_IOCTL_RANGE(USB_QUIRK_NAME_GET):
 		pgq = (void *)data;
 		x = pgq->index;
 		if (x >= USB_QUIRK_MAX) {
@@ -722,7 +722,7 @@
 		    usb_quirkstr(x), sizeof(pgq->quirkname));
 		return (0);		/* success */
 
-	case USB_DEV_QUIRK_ADD:
+	case USB_IOCTL_RANGE(USB_DEV_QUIRK_ADD):
 		pgq = (void *)data;
 
 		/* check privileges */
@@ -761,7 +761,7 @@
 		}
 		return (0);		/* success */
 
-	case USB_DEV_QUIRK_REMOVE:
+	case USB_IOCTL_RANGE(USB_DEV_QUIRK_REMOVE):
 		pgq = (void *)data;
 		/* check privileges */
 		err = priv_check(curthread, PRIV_DRIVER);
=== sys/dev/usb/usb_compat_linux.c
==================================================================
--- sys/dev/usb/usb_compat_linux.c	(revision 253548)
+++ sys/dev/usb/usb_compat_linux.c	(local)
@@ -48,7 +48,6 @@
 #include <sys/priv.h>
 
 #include <dev/usb/usb.h>
-#include <dev/usb/usb_ioctl.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
 
=== sys/dev/usb/usb_dev.c
==================================================================
--- sys/dev/usb/usb_dev.c	(revision 253548)
+++ sys/dev/usb/usb_dev.c	(local)
@@ -1497,30 +1497,30 @@
 	int err;
 
 	u.data = data;
-	switch (cmd) {
-		case USB_READ_DIR:
-			err = usb_read_symlink(u.urd->urd_data,
-			    u.urd->urd_startentry, u.urd->urd_maxlen);
+	switch (USB_IOCTL_SWAP(cmd)) {
+	case USB_IOCTL_RANGE(USB_READ_DIR):
+		err = usb_read_symlink(u.urd->urd_data,
+		    u.urd->urd_startentry, u.urd->urd_maxlen);
+		break;
+	case USB_IOCTL_RANGE(USB_DEV_QUIRK_GET):
+	case USB_IOCTL_RANGE(USB_QUIRK_NAME_GET):
+	case USB_IOCTL_RANGE(USB_DEV_QUIRK_ADD):
+	case USB_IOCTL_RANGE(USB_DEV_QUIRK_REMOVE):
+		err = usb_quirk_ioctl_p(cmd, data, fflag, td);
+		break;
+	case USB_IOCTL_RANGE(USB_GET_TEMPLATE):
+		*(int *)data = usb_template;
+		err = 0;
+		break;
+	case USB_IOCTL_RANGE(USB_SET_TEMPLATE):
+		err = priv_check(curthread, PRIV_DRIVER);
+		if (err)
 			break;
-		case USB_DEV_QUIRK_GET:
-		case USB_QUIRK_NAME_GET:
-		case USB_DEV_QUIRK_ADD:
-		case USB_DEV_QUIRK_REMOVE:
-			err = usb_quirk_ioctl_p(cmd, data, fflag, td);
-			break;
-		case USB_GET_TEMPLATE:
-			*(int *)data = usb_template;
-			err = 0;
-			break;
-		case USB_SET_TEMPLATE:
-			err = priv_check(curthread, PRIV_DRIVER);
-			if (err)
-				break;
-			usb_template = *(int *)data;
-			break;
-		default:
-			err = ENOTTY;
-			break;
+		usb_template = *(int *)data;
+		break;
+	default:
+		err = ENOTTY;
+		break;
 	}
 	return (err);
 }
=== sys/dev/usb/usb_generic.c
==================================================================
--- sys/dev/usb/usb_generic.c	(revision 253548)
+++ sys/dev/usb/usb_generic.c	(local)
@@ -1424,8 +1424,8 @@
 
 	DPRINTFN(6, "cmd=0x%08lx\n", cmd);
 
-	switch (cmd) {
-	case USB_FS_COMPLETE:
+	switch (USB_IOCTL_SWAP(cmd)) {
+	case USB_IOCTL_RANGE(USB_FS_COMPLETE):
 		mtx_lock(f->priv_mtx);
 		error = ugen_fs_get_complete(f, &ep_index);
 		mtx_unlock(f->priv_mtx);
@@ -1438,7 +1438,7 @@
 		error = ugen_fs_copy_out(f, u.pcomp->ep_index);
 		break;
 
-	case USB_FS_START:
+	case USB_IOCTL_RANGE(USB_FS_START):
 		error = ugen_fs_copy_in(f, u.pstart->ep_index);
 		if (error)
 			break;
@@ -1448,7 +1448,7 @@
 		mtx_unlock(f->priv_mtx);
 		break;
 
-	case USB_FS_STOP:
+	case USB_IOCTL_RANGE(USB_FS_STOP):
 		if (u.pstop->ep_index >= f->fs_ep_max) {
 			error = EINVAL;
 			break;
@@ -1470,8 +1470,8 @@
 		mtx_unlock(f->priv_mtx);
 		break;
 
-	case USB_FS_OPEN:
-	case USB_FS_OPEN_STREAM:
+	case USB_IOCTL_RANGE(USB_FS_OPEN):
+	case USB_IOCTL_RANGE(USB_FS_OPEN_STREAM):
 		if (u.popen->ep_index >= f->fs_ep_max) {
 			error = EINVAL;
 			break;
@@ -1523,7 +1523,7 @@
 		usb_config[0].frames = u.popen->max_frames;
 		usb_config[0].bufsize = u.popen->max_bufsize;
 		usb_config[0].usb_mode = USB_MODE_DUAL;	/* both modes */
-		if (cmd == USB_FS_OPEN_STREAM)
+		if (IOCBASECMD(cmd) == IOCBASECMD(USB_FS_OPEN_STREAM))
 			usb_config[0].stream_id = u.popen_stream->stream_id;
 
 		if (usb_config[0].type == UE_CONTROL) {
@@ -1572,7 +1572,7 @@
 		}
 		break;
 
-	case USB_FS_CLOSE:
+	case USB_IOCTL_RANGE(USB_FS_CLOSE):
 		if (u.pclose->ep_index >= f->fs_ep_max) {
 			error = EINVAL;
 			break;
@@ -1584,7 +1584,7 @@
 		usbd_transfer_unsetup(f->fs_xfer + u.pclose->ep_index, 1);
 		break;
 
-	case USB_FS_CLEAR_STALL_SYNC:
+	case USB_IOCTL_RANGE(USB_FS_CLEAR_STALL_SYNC):
 		if (u.pstall->ep_index >= f->fs_ep_max) {
 			error = EINVAL;
 			break;
@@ -1941,8 +1941,8 @@
 	f_rx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_RX];
 	f_tx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_TX];
 
-	switch (cmd) {
-	case USB_SET_RX_SHORT_XFER:
+	switch (USB_IOCTL_SWAP(cmd)) {
+	case USB_IOCTL_RANGE(USB_SET_RX_SHORT_XFER):
 		if (fflags & FREAD) {
 			error = ugen_set_short_xfer(f_rx, addr);
 		} else {
@@ -1950,7 +1950,7 @@
 		}
 		break;
 
-	case USB_SET_TX_FORCE_SHORT:
+	case USB_IOCTL_RANGE(USB_SET_TX_FORCE_SHORT):
 		if (fflags & FWRITE) {
 			error = ugen_set_short_xfer(f_tx, addr);
 		} else {
@@ -1958,7 +1958,7 @@
 		}
 		break;
 
-	case USB_SET_RX_TIMEOUT:
+	case USB_IOCTL_RANGE(USB_SET_RX_TIMEOUT):
 		if (fflags & FREAD) {
 			error = ugen_set_timeout(f_rx, addr);
 		} else {
@@ -1966,7 +1966,7 @@
 		}
 		break;
 
-	case USB_SET_TX_TIMEOUT:
+	case USB_IOCTL_RANGE(USB_SET_TX_TIMEOUT):
 		if (fflags & FWRITE) {
 			error = ugen_set_timeout(f_tx, addr);
 		} else {
@@ -1974,7 +1974,7 @@
 		}
 		break;
 
-	case USB_GET_RX_FRAME_SIZE:
+	case USB_IOCTL_RANGE(USB_GET_RX_FRAME_SIZE):
 		if (fflags & FREAD) {
 			error = ugen_get_frame_size(f_rx, addr);
 		} else {
@@ -1982,7 +1982,7 @@
 		}
 		break;
 
-	case USB_GET_TX_FRAME_SIZE:
+	case USB_IOCTL_RANGE(USB_GET_TX_FRAME_SIZE):
 		if (fflags & FWRITE) {
 			error = ugen_get_frame_size(f_tx, addr);
 		} else {
@@ -1990,7 +1990,7 @@
 		}
 		break;
 
-	case USB_SET_RX_BUFFER_SIZE:
+	case USB_IOCTL_RANGE(USB_SET_RX_BUFFER_SIZE):
 		if (fflags & FREAD) {
 			error = ugen_set_buffer_size(f_rx, addr);
 		} else {
@@ -1998,7 +1998,7 @@
 		}
 		break;
 
-	case USB_SET_TX_BUFFER_SIZE:
+	case USB_IOCTL_RANGE(USB_SET_TX_BUFFER_SIZE):
 		if (fflags & FWRITE) {
 			error = ugen_set_buffer_size(f_tx, addr);
 		} else {
@@ -2006,7 +2006,7 @@
 		}
 		break;
 
-	case USB_GET_RX_BUFFER_SIZE:
+	case USB_IOCTL_RANGE(USB_GET_RX_BUFFER_SIZE):
 		if (fflags & FREAD) {
 			error = ugen_get_buffer_size(f_rx, addr);
 		} else {
@@ -2014,7 +2014,7 @@
 		}
 		break;
 
-	case USB_GET_TX_BUFFER_SIZE:
+	case USB_IOCTL_RANGE(USB_GET_TX_BUFFER_SIZE):
 		if (fflags & FWRITE) {
 			error = ugen_get_buffer_size(f_tx, addr);
 		} else {
@@ -2022,7 +2022,7 @@
 		}
 		break;
 
-	case USB_GET_RX_INTERFACE_DESC:
+	case USB_IOCTL_RANGE(USB_GET_RX_INTERFACE_DESC):
 		if (fflags & FREAD) {
 			error = ugen_get_iface_desc(f_rx, addr);
 		} else {
@@ -2030,7 +2030,7 @@
 		}
 		break;
 
-	case USB_GET_TX_INTERFACE_DESC:
+	case USB_IOCTL_RANGE(USB_GET_TX_INTERFACE_DESC):
 		if (fflags & FWRITE) {
 			error = ugen_get_iface_desc(f_tx, addr);
 		} else {
@@ -2038,7 +2038,7 @@
 		}
 		break;
 
-	case USB_GET_RX_ENDPOINT_DESC:
+	case USB_IOCTL_RANGE(USB_GET_RX_ENDPOINT_DESC):
 		if (fflags & FREAD) {
 			error = ugen_get_endpoint_desc(f_rx, addr);
 		} else {
@@ -2046,7 +2046,7 @@
 		}
 		break;
 
-	case USB_GET_TX_ENDPOINT_DESC:
+	case USB_IOCTL_RANGE(USB_GET_TX_ENDPOINT_DESC):
 		if (fflags & FWRITE) {
 			error = ugen_get_endpoint_desc(f_tx, addr);
 		} else {
@@ -2054,13 +2054,13 @@
 		}
 		break;
 
-	case USB_SET_RX_STALL_FLAG:
+	case USB_IOCTL_RANGE(USB_SET_RX_STALL_FLAG):
 		if ((fflags & FREAD) && (*(int *)addr)) {
 			f_rx->flag_stall = 1;
 		}
 		break;
 
-	case USB_SET_TX_STALL_FLAG:
+	case USB_IOCTL_RANGE(USB_SET_TX_STALL_FLAG):
 		if ((fflags & FWRITE) && (*(int *)addr)) {
 			f_tx->flag_stall = 1;
 		}
@@ -2099,12 +2099,12 @@
 
 	DPRINTFN(6, "cmd=0x%08lx\n", cmd);
 
-	switch (cmd) {
-	case USB_DISCOVER:
+	switch (USB_IOCTL_SWAP(cmd)) {
+	case USB_IOCTL_RANGE(USB_DISCOVER):
 		usb_needs_explore_all();
 		break;
 
-	case USB_SETDEBUG:
+	case USB_IOCTL_RANGE(USB_SETDEBUG):
 		if (!(fflags & FWRITE)) {
 			error = EPERM;
 			break;
@@ -2112,11 +2112,11 @@
 		usb_debug = *(int *)addr;
 		break;
 
-	case USB_GET_CONFIG:
+	case USB_IOCTL_RANGE(USB_GET_CONFIG):
 		*(int *)addr = f->udev->curr_config_index;
 		break;
 
-	case USB_SET_CONFIG:
+	case USB_IOCTL_RANGE(USB_SET_CONFIG):
 		if (!(fflags & FWRITE)) {
 			error = EPERM;
 			break;
@@ -2124,7 +2124,7 @@
 		error = ugen_set_config(f, *(int *)addr);
 		break;
 
-	case USB_GET_ALTINTERFACE:
+	case USB_IOCTL_RANGE(USB_GET_ALTINTERFACE):
 		iface = usbd_get_iface(f->udev,
 		    u.ai->uai_interface_index);
 		if (iface && iface->idesc) {
@@ -2134,7 +2134,7 @@
 		}
 		break;
 
-	case USB_SET_ALTINTERFACE:
+	case USB_IOCTL_RANGE(USB_SET_ALTINTERFACE):
 		if (!(fflags & FWRITE)) {
 			error = EPERM;
 			break;
@@ -2143,7 +2143,7 @@
 		    u.ai->uai_interface_index, u.ai->uai_alt_index);
 		break;
 
-	case USB_GET_DEVICE_DESC:
+	case USB_IOCTL_RANGE(USB_GET_DEVICE_DESC):
 		dtemp = usbd_get_device_descriptor(f->udev);
 		if (!dtemp) {
 			error = EIO;
@@ -2152,7 +2152,7 @@
 		*u.ddesc = *dtemp;
 		break;
 
-	case USB_GET_CONFIG_DESC:
+	case USB_IOCTL_RANGE(USB_GET_CONFIG_DESC):
 		ctemp = usbd_get_config_descriptor(f->udev);
 		if (!ctemp) {
 			error = EIO;
@@ -2161,20 +2161,20 @@
 		*u.cdesc = *ctemp;
 		break;
 
-	case USB_GET_FULL_DESC:
+	case USB_IOCTL_RANGE(USB_GET_FULL_DESC):
 		error = ugen_get_cdesc(f, addr);
 		break;
 
-	case USB_GET_STRING_DESC:
+	case USB_IOCTL_RANGE(USB_GET_STRING_DESC):
 		error = ugen_get_sdesc(f, addr);
 		break;
 
-	case USB_GET_IFACE_DRIVER:
+	case USB_IOCTL_RANGE(USB_GET_IFACE_DRIVER):
 		error = ugen_get_iface_driver(f, addr);
 		break;
 
-	case USB_REQUEST:
-	case USB_DO_REQUEST:
+	case USB_IOCTL_RANGE(USB_REQUEST):
+	case USB_IOCTL_RANGE(USB_DO_REQUEST):
 		if (!(fflags & FWRITE)) {
 			error = EPERM;
 			break;
@@ -2182,12 +2182,12 @@
 		error = ugen_do_request(f, addr);
 		break;
 
-	case USB_DEVICEINFO:
-	case USB_GET_DEVICEINFO:
+	case USB_IOCTL_RANGE(USB_DEVICEINFO):
+	case USB_IOCTL_RANGE(USB_GET_DEVICEINFO):
 		error = usb_gen_fill_deviceinfo(f, addr);
 		break;
 
-	case USB_DEVICESTATS:
+	case USB_IOCTL_RANGE(USB_DEVICESTATS):
 		for (n = 0; n != 4; n++) {
 
 			u.stat->uds_requests_fail[n] =
@@ -2198,20 +2198,20 @@
 		}
 		break;
 
-	case USB_DEVICEENUMERATE:
+	case USB_IOCTL_RANGE(USB_DEVICEENUMERATE):
 		error = ugen_re_enumerate(f);
 		break;
 
-	case USB_GET_PLUGTIME:
+	case USB_IOCTL_RANGE(USB_GET_PLUGTIME):
 		*u.ptime = f->udev->plugtime;
 		break;
 
-	case USB_CLAIM_INTERFACE:
-	case USB_RELEASE_INTERFACE:
+	case USB_IOCTL_RANGE(USB_CLAIM_INTERFACE):
+	case USB_IOCTL_RANGE(USB_RELEASE_INTERFACE):
 		/* TODO */
 		break;
 
-	case USB_IFACE_DRIVER_ACTIVE:
+	case USB_IOCTL_RANGE(USB_IFACE_DRIVER_ACTIVE):
 
 		n = *u.pint & 0xFF;
 
@@ -2223,7 +2223,7 @@
 			error = ENXIO;
 		break;
 
-	case USB_IFACE_DRIVER_DETACH:
+	case USB_IOCTL_RANGE(USB_IFACE_DRIVER_DETACH):
 
 		error = priv_check(curthread, PRIV_DRIVER);
 
@@ -2249,33 +2249,33 @@
 		usbd_set_parent_iface(f->udev, n, n);
 		break;
 
-	case USB_SET_POWER_MODE:
+	case USB_IOCTL_RANGE(USB_SET_POWER_MODE):
 		error = ugen_set_power_mode(f, *u.pint);
 		break;
 
-	case USB_GET_POWER_MODE:
+	case USB_IOCTL_RANGE(USB_GET_POWER_MODE):
 		*u.pint = ugen_get_power_mode(f);
 		break;
 
-	case USB_GET_DEV_PORT_PATH:
+	case USB_IOCTL_RANGE(USB_GET_DEV_PORT_PATH):
 		error = ugen_get_port_path(f, u.dpp);
 		break;
 
-	case USB_GET_POWER_USAGE:
+	case USB_IOCTL_RANGE(USB_GET_POWER_USAGE):
 		*u.pint = ugen_get_power_usage(f);
 		break;
 
-	case USB_SET_PORT_ENABLE:
+	case USB_IOCTL_RANGE(USB_SET_PORT_ENABLE):
 		error = ugen_do_port_feature(f,
 		    *u.pint, 1, UHF_PORT_ENABLE);
 		break;
 
-	case USB_SET_PORT_DISABLE:
+	case USB_IOCTL_RANGE(USB_SET_PORT_DISABLE):
 		error = ugen_do_port_feature(f,
 		    *u.pint, 0, UHF_PORT_ENABLE);
 		break;
 
-	case USB_FS_INIT:
+	case USB_IOCTL_RANGE(USB_FS_INIT):
 		/* verify input parameters */
 		if (u.pinit->pEndpoints == NULL) {
 			error = EINVAL;
@@ -2316,7 +2316,7 @@
 		f->fs_ep_ptr = u.pinit->pEndpoints;
 		break;
 
-	case USB_FS_UNINIT:
+	case USB_IOCTL_RANGE(USB_FS_UNINIT):
 		if (u.puninit->dummy != 0) {
 			error = EINVAL;
 			break;
=== sys/dev/usb/usb_hub.c
==================================================================
--- sys/dev/usb/usb_hub.c	(revision 253548)
+++ sys/dev/usb/usb_hub.c	(local)
@@ -53,7 +53,6 @@
 #include <sys/priv.h>
 
 #include <dev/usb/usb.h>
-#include <dev/usb/usb_ioctl.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
 
=== sys/dev/usb/usb_ioctl.h
==================================================================
--- sys/dev/usb/usb_ioctl.h	(revision 253548)
+++ sys/dev/usb/usb_ioctl.h	(local)
@@ -42,7 +42,31 @@
 #define	USB_DEVICE_DIR "usb"
 #define	USB_GENERIC_NAME "ugen"
 #define	USB_TEMPLATE_SYSCTL "hw.usb.template"	/* integer type */
+#define	USB_IOCTL_ALIGN_MAX 8	/* bytes */
 
+/* Make sure we get the length field at LSB */
+#ifndef USB_IOCTL_SWAP
+#define	USB_IOCTL_SWAP(cmd)						\
+    ((uint32_t)((((uint32_t)(cmd)) << 16) | (((uint32_t)(cmd)) >> 16)))
+#endif
+
+/* Align IOCTL structure size */
+#ifndef USB_IOCTL_ALIGN
+#define	USB_IOCTL_ALIGN(cmd)				\
+    (USB_IOCTL_SWAP(cmd) +				\
+    ((USB_IOCTL_ALIGN_MAX - (USB_IOCTL_SWAP(cmd) %	\
+    USB_IOCTL_ALIGN_MAX)) % USB_IOCTL_ALIGN_MAX))
+#endif
+
+/*
+ * Switch case for IOCTLs. Mostly useful for hiding differences when
+ * running 32-bit programs under 64-bit kernels:
+ */
+#ifndef USB_IOCTL_RANGE
+#define	USB_IOCTL_RANGE(cmd)			\
+  USB_IOCTL_SWAP(cmd) ... USB_IOCTL_ALIGN(cmd)
+#endif
+
 /* Definition of valid template sysctl values */
 
 enum {
@@ -218,7 +242,14 @@
 };
 
 struct usb_fs_open_stream {
-	struct usb_fs_open fs_open;
+	/* same as "usb_fs_open" */
+	uint32_t max_bufsize;
+	uint32_t max_frames;
+	uint16_t max_packet_length;
+	uint8_t	dev_index;
+	uint8_t	ep_index;
+	uint8_t	ep_no;
+	/* stream ID */
 	uint16_t stream_id;
 };
 
=== sys/dev/usb/usb_request.c
==================================================================
--- sys/dev/usb/usb_request.c	(revision 253548)
+++ sys/dev/usb/usb_request.c	(local)
@@ -51,7 +51,6 @@
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_ioctl.h>
 #include <dev/usb/usbhid.h>
 
 #define	USB_DEBUG_VAR usb_debug

--------------000209000009070500010606--



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