This bugfix is incomplete. Isochronous transfers are still broken, when running 32-bit software on a 64-bit kernel. Function processcompl_compat() in devio.c needs a similar fix to the fix that was applied to processcompl(). Looking at processcompl_compat() I see:
if (as->userbuffer && urb->actual_length)
if (copy_to_user(as->userbuffer, urb->transfer_buffer,
urb->actual_length))
return -EFAULT;
correct code would be something like
if (as->userbuffer && urb->actual_length) {
if (urb->number_of_packets > 0) /* Isochronous */
i = urb->transfer_buffer_length;
else /* Non-Isoc */
i = urb->actual_length;
if (copy_to_user(as->userbuffer, urb->transfer_buffer, i))
goto err_out;
}
(note the difference between urb->actual_length and urb->transfer_buffer_length).
With kernel 2.6.32-23-generic x86_64 on Ubuntu 10.04, using proprietary USB-hardware hooked up to the USB bus (with software compiled for 32-bit), I can directly observe how isochronous transfers retrieved via ioctl(.. USBDEVFS_REAPURB ..) are too short, i.e. the kernel does not write the end of the data packet to the supplied buffer. Booting on the 2.6.31 kernel still present from before I upgraded from Ubuntu 9.10, the same software runs flawlessly.
As a workaround I'll use the older kernel for now (also I could compile for 64-bit, actually...).
This bugfix is incomplete. Isochronous transfers are still broken, when running 32-bit software on a 64-bit kernel. Function processcompl_ compat( ) in devio.c needs a similar fix to the fix that was applied to processcompl(). Looking at processcompl_ compat( ) I see:
if (as->userbuffer && urb->actual_length) user(as- >userbuffer, urb->transfer_ buffer, >actual_ length) )
if (copy_to_
urb-
return -EFAULT;
correct code would be something like
if (as->userbuffer && urb->actual_length) { of_packets > 0) /* Isochronous */ buffer_ length; user(as- >userbuffer, urb->transfer_ buffer, i))
if (urb->number_
i = urb->transfer_
else /* Non-Isoc */
i = urb->actual_length;
if (copy_to_
goto err_out;
}
(note the difference between urb->actual_length and urb->transfer_ buffer_ length) .
With kernel 2.6.32-23-generic x86_64 on Ubuntu 10.04, using proprietary USB-hardware hooked up to the USB bus (with software compiled for 32-bit), I can directly observe how isochronous transfers retrieved via ioctl(.. USBDEVFS_REAPURB ..) are too short, i.e. the kernel does not write the end of the data packet to the supplied buffer. Booting on the 2.6.31 kernel still present from before I upgraded from Ubuntu 9.10, the same software runs flawlessly.
As a workaround I'll use the older kernel for now (also I could compile for 64-bit, actually...).
cheers,
David