svn commit: r213852 - in head: lib/libusb sys/dev/usb

Kostik Belousov kostikbel at gmail.com
Sat Oct 16 13:28:01 UTC 2010


On Sat, Oct 16, 2010 at 01:30:31PM +0200, Hans Petter Selasky wrote:
> On Saturday 16 October 2010 12:12:43 Hans Petter Selasky wrote:
> > On Saturday 16 October 2010 12:00:51 Kostik Belousov wrote:
> > > > USB has some shared memory structures which are used in both user-land
> > > > and  kernel, which are not part of IOCTLs. Your approach means that
> > > > there are two sets of IOCTL's of all kinds, one for 32-bit and one for
> > > > 64-bit?
> > > 
> > > For all kinds of structures that are not ABI-invariant, yes.
> > 
> 
> Hi,
> 
> I've committed a patch to fix the buildworld breakage after feedback from 
> Andreas Tobler.
> 
> http://svn.freebsd.org/changeset/base/213920
> 
> > The approach that was discussed by me and Andrew earlier this year, was to
> > use uint64_t instead of "void *" in shared memory structures. The only
> > disadvantage is that this will force you to recompile libusb when you
> > update the kernel, and so we kind of put that approach aside to keep
> > seamless upgrade compatibility.
> 
> This will also break the ABI on 8-stable and that was the main reason for 
> going the other route. However, most applications access USB via libusb, so 
> the breakage would probably be minimal. Do you have any opinions here? Should 
> we make an exception for the general rule to not change the ABI within a 
> stable branch?
> 
> I'm attaching the other approach, which allows both 32 and 64 bit applications 
> to use USB using the same IOCTL's.
> 
> See thread: [FreeBSD 8/9] [64-bit IOCTL] Using the USB stack from a 32-bit 
> application under a 64-bit kernel.
> 
This is a choice of the poison :).

Ideally, you would switch to the new ABI and keep old ABI shims around
for binary compatibility. In essence, this is equivalent to the proper
32bit compat shims.

> --HPS

> --- src/lib/libusb/libusb20.c	2010-03-08 16:57:53.000000000 0000
> +++ src/lib/libusb/libusb20.c	2010-03-08 16:57:53.000000000 0000
> @@ -320,7 +320,7 @@
>  void
>  libusb20_tr_set_buffer(struct libusb20_transfer *xfer, void *buffer, uint16_t frIndex)
>  {
> -	xfer->ppBuffer[frIndex] = buffer;
> +	xfer->ppBuffer[frIndex] = libusb20_u64ptr(buffer);
>  	return;
>  }
>  
> @@ -386,7 +386,7 @@
>  void
>  libusb20_tr_setup_bulk(struct libusb20_transfer *xfer, void *pBuf, uint32_t length, uint32_t timeout)
>  {
> -	xfer->ppBuffer[0] = pBuf;
> +	xfer->ppBuffer[0] = libusb20_u64ptr(pBuf);
>  	xfer->pLength[0] = length;
>  	xfer->timeout = timeout;
>  	xfer->nFrames = 1;
> @@ -398,7 +398,7 @@
>  {
>  	uint16_t len;
>  
> -	xfer->ppBuffer[0] = psetup;
> +	xfer->ppBuffer[0] = libusb20_u64ptr(psetup);
>  	xfer->pLength[0] = 8;		/* fixed */
>  	xfer->timeout = timeout;
>  
> @@ -406,7 +406,7 @@
>  
>  	if (len != 0) {
>  		xfer->nFrames = 2;
> -		xfer->ppBuffer[1] = pBuf;
> +		xfer->ppBuffer[1] = libusb20_u64ptr(pBuf);
>  		xfer->pLength[1] = len;
>  	} else {
>  		xfer->nFrames = 1;
> @@ -417,7 +417,7 @@
>  void
>  libusb20_tr_setup_intr(struct libusb20_transfer *xfer, void *pBuf, uint32_t length, uint32_t timeout)
>  {
> -	xfer->ppBuffer[0] = pBuf;
> +	xfer->ppBuffer[0] = libusb20_u64ptr(pBuf);
>  	xfer->pLength[0] = length;
>  	xfer->timeout = timeout;
>  	xfer->nFrames = 1;
> @@ -431,7 +431,7 @@
>  		/* should not happen */
>  		return;
>  	}
> -	xfer->ppBuffer[frIndex] = pBuf;
> +	xfer->ppBuffer[frIndex] = libusb20_u64ptr(pBuf);
>  	xfer->pLength[frIndex] = length;
>  	return;
>  }
> --- src/lib/libusb/libusb20_int.h	2010-03-08 16:57:53.000000000 0000
> +++ src/lib/libusb/libusb20_int.h	2010-03-08 16:57:53.000000000 0000
> @@ -31,6 +31,8 @@
>  #ifndef _LIBUSB20_INT_H_
>  #define	_LIBUSB20_INT_H_
>  
> +#define	libusb20_u64ptr(ptr)	((uint64_t)(uintptr_t)(ptr))
> +
>  struct libusb20_device;
>  struct libusb20_backend;
>  struct libusb20_transfer;
> @@ -148,7 +150,7 @@
>  	/*
>  	 * Pointer to a list of buffer pointers:
>  	 */
> -	void  **ppBuffer;
> +	uint64_t *ppBuffer;
>  	/*
>  	 * Pointer to frame lengths, which are updated to actual length
>  	 * after the USB transfer completes:
> --- src/lib/libusb/libusb20_ugen20.c	2010-03-08 16:57:53.000000000 0000
> +++ src/lib/libusb/libusb20_ugen20.c	2010-03-08 16:57:53.000000000 0000
> @@ -763,8 +763,8 @@
>  	xfer->maxPacketLen = temp.max_packet_length;
>  
>  	/* setup buffer and length lists */
> -	fsep->ppBuffer = xfer->ppBuffer;/* zero copy */
> -	fsep->pLength = xfer->pLength;	/* zero copy */
> +	fsep->ppBuffer = libusb20_u64ptr(xfer->ppBuffer);	/* zero copy */
> +	fsep->pLength = libusb20_u64ptr(xfer->pLength);		/* zero copy */
>  
>  	return (0);			/* success */
>  }
> --- src/sys/dev/usb/usb_generic.c	2010-05-17 04:19:10.000000000 0000
> +++ src/sys/dev/usb/usb_generic.c	2010-05-17 04:19:10.000000000 0000
> @@ -76,6 +76,7 @@
>  #define	UGEN_BULK_FS_BUFFER_SIZE	(64*32)	/* bytes */
>  #define	UGEN_BULK_HS_BUFFER_SIZE	(1024*32)	/* bytes */
>  #define	UGEN_HW_FRAMES	50		/* number of milliseconds per transfer */
> +#define	UGEN_HW_PTR(u64)		((void *)(uintptr_t)(u64))
>  
>  /* function prototypes */
>  
> @@ -134,7 +135,6 @@
>  TUNABLE_INT("hw.usb.ugen.debug", &ugen_debug);
>  #endif
>  
> -
>  /* prototypes */
>  
>  static int
> @@ -1039,7 +1039,7 @@
>  	struct usb_device_request *req;
>  	struct usb_xfer *xfer;
>  	struct usb_fs_endpoint fs_ep;
> -	void *uaddr;			/* userland pointer */
> +	uint64_t uaddr;			/* userland pointer */
>  	void *kaddr;
>  	usb_frlength_t offset;
>  	usb_frlength_t rem;
> @@ -1077,11 +1077,13 @@
>  		xfer->error = USB_ERR_INVAL;
>  		goto complete;
>  	}
> -	error = copyin(fs_ep.ppBuffer,
> +
> +	/* read frame buffer pointer */
> +	error = copyin(UGEN_HW_PTR(fs_ep.ppBuffer),
>  	    &uaddr, sizeof(uaddr));
> -	if (error) {
> +	if (error)
>  		return (error);
> -	}
> +
>  	/* reset first frame */
>  	usbd_xfer_set_frame_offset(xfer, 0, 0);
>  
> @@ -1089,7 +1091,8 @@
>  
>  		req = xfer->frbuffers[0].buffer;
>  
> -		error = copyin(fs_ep.pLength,
> +		/* read frame buffer length */
> +		error = copyin(UGEN_HW_PTR(fs_ep.pLength),
>  		    &length, sizeof(length));
>  		if (error) {
>  			return (error);
> @@ -1099,7 +1102,7 @@
>  			goto complete;
>  		}
>  		if (length != 0) {
> -			error = copyin(uaddr, req, length);
> +			error = copyin(UGEN_HW_PTR(uaddr), req, length);
>  			if (error) {
>  				return (error);
>  			}
> @@ -1159,11 +1162,12 @@
>  
>  	for (; n != xfer->nframes; n++) {
>  
> -		error = copyin(fs_ep.pLength + n,
> +		/* read frame buffer length */
> +		error = copyin(UGEN_HW_PTR(fs_ep.pLength + (4 * n)),
>  		    &length, sizeof(length));
> -		if (error) {
> +		if (error)
>  			break;
> -		}
> +
>  		usbd_xfer_set_frame_len(xfer, n, length);
>  
>  		if (length > rem) {
> @@ -1174,12 +1178,12 @@
>  
>  		if (!isread) {
>  
> -			/* we need to know the source buffer */
> -			error = copyin(fs_ep.ppBuffer + n,
> +			/* read frame buffer pointer */
> +			error = copyin(UGEN_HW_PTR(fs_ep.ppBuffer + (8 * n)),
>  			    &uaddr, sizeof(uaddr));
> -			if (error) {
> +			if (error)
>  				break;
> -			}
> +
>  			if (xfer->flags_int.isochronous_xfr) {
>  				/* get kernel buffer address */
>  				kaddr = xfer->frbuffers[0].buffer;
> @@ -1193,7 +1197,7 @@
>  			}
>  
>  			/* move data */
> -			error = copyin(uaddr, kaddr, length);
> +			error = copyin(UGEN_HW_PTR(uaddr), kaddr, length);
>  			if (error) {
>  				break;
>  			}
> @@ -1216,7 +1220,7 @@
>  	struct usb_xfer *xfer;
>  	struct usb_fs_endpoint fs_ep;
>  	struct usb_fs_endpoint *fs_ep_uptr;	/* userland ptr */
> -	void *uaddr;			/* userland ptr */
> +	uint64_t uaddr;			/* userland ptr */
>  	void *kaddr;
>  	usb_frlength_t offset;
>  	usb_frlength_t rem;
> @@ -1281,12 +1285,12 @@
>  
>  	for (; n != xfer->nframes; n++) {
>  
> -		/* get initial length into "temp" */
> -		error = copyin(fs_ep.pLength + n,
> +		/* get initial frame buffer length into "temp" */
> +		error = copyin(UGEN_HW_PTR(fs_ep.pLength + (4 * n)),
>  		    &temp, sizeof(temp));
> -		if (error) {
> +		if (error)
>  			return (error);
> -		}
> +
>  		if (temp > rem) {
>  			/* the userland length has been corrupted */
>  			DPRINTF("corrupt userland length "
> @@ -1307,12 +1311,12 @@
>  		}
>  		if (isread) {
>  
> -			/* we need to know the destination buffer */
> -			error = copyin(fs_ep.ppBuffer + n,
> +			/* read destination frame buffer pointer */
> +			error = copyin(UGEN_HW_PTR(fs_ep.ppBuffer + (8 * n)),
>  			    &uaddr, sizeof(uaddr));
> -			if (error) {
> +			if (error)
>  				return (error);
> -			}
> +
>  			if (xfer->flags_int.isochronous_xfr) {
>  				/* only one frame buffer */
>  				kaddr = USB_ADD_BYTES(
> @@ -1323,7 +1327,7 @@
>  			}
>  
>  			/* move data */
> -			error = copyout(kaddr, uaddr, length);
> +			error = copyout(kaddr, UGEN_HW_PTR(uaddr), length);
>  			if (error) {
>  				return (error);
>  			}
> @@ -1334,12 +1338,11 @@
>  		 */
>  		offset += temp;
>  
> -		/* update length */
> +		/* update frame buffer length */
>  		error = copyout(&length,
> -		    fs_ep.pLength + n, sizeof(length));
> -		if (error) {
> +		    UGEN_HW_PTR(fs_ep.pLength + (4 * n)), sizeof(length));
> +		if (error)
>  			return (error);
> -		}
>  	}
>  
>  complete:
> --- src/sys/dev/usb/usb_ioctl.h	2010-02-14 12:03:51.000000000 0000
> +++ src/sys/dev/usb/usb_ioctl.h	2010-02-14 12:03:51.000000000 0000
> @@ -131,9 +131,10 @@
>  	 * NOTE: isochronous USB transfer only use one buffer, but can have
>  	 * multiple frame lengths !
>  	 */
> -	void  **ppBuffer;		/* pointer to userland buffers */
> -	uint32_t *pLength;		/* pointer to frame lengths, updated
> -					 * to actual length */
> +	uint64_t ppBuffer;		/* pointer to 64-bit userland buffer pointers */
> +	uint64_t pLength;		/* pointer to 32-bit frame lengths, which
> +					 * get updated to the actual length after
> +					 * the transfer is complete. */
>  	uint32_t nFrames;		/* number of frames */
>  	uint32_t aFrames;		/* actual number of frames */
>  	uint16_t flags;

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/svn-src-all/attachments/20101016/1947e85a/attachment.pgp


More information about the svn-src-all mailing list