svn commit: r200323 - stable/8/sys/dev/usb
Andrew Thompson
thompsa at FreeBSD.org
Wed Dec 9 14:32:37 PST 2009
Author: thompsa
Date: Wed Dec 9 22:32:36 2009
New Revision: 200323
URL: http://svn.freebsd.org/changeset/base/200323
Log:
MFC r198776
- Add usb_fill_bulk_urb() and usb_bulk_msg() linux compat functions [1]
- Don't write actual length if the actual length pointer is NULL [2]
- correct Linux Compatibility error codes for short isochronous IN transfers
and make status field signed.
Submitted by: Leunam Elebek [1], Manuel Gebele [2]
Modified:
stable/8/sys/dev/usb/usb_compat_linux.c
stable/8/sys/dev/usb/usb_compat_linux.h
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/dev/usb/usb_compat_linux.c
==============================================================================
--- stable/8/sys/dev/usb/usb_compat_linux.c Wed Dec 9 22:31:45 2009 (r200322)
+++ stable/8/sys/dev/usb/usb_compat_linux.c Wed Dec 9 22:32:36 2009 (r200323)
@@ -624,10 +624,11 @@ usb_start_wait_urb(struct urb *urb, usb_
done:
if (do_unlock)
mtx_unlock(&Giant);
- if (err) {
- *p_actlen = 0;
- } else {
- *p_actlen = urb->actual_length;
+ if (p_actlen != NULL) {
+ if (err)
+ *p_actlen = 0;
+ else
+ *p_actlen = urb->actual_length;
}
return (err);
}
@@ -1362,8 +1363,17 @@ usb_linux_isoc_callback(struct usb_xfer
for (x = 0; x < urb->number_of_packets; x++) {
uipd = urb->iso_frame_desc + x;
+ if (uipd->length > xfer->frlengths[x]) {
+ if (urb->transfer_flags & URB_SHORT_NOT_OK) {
+ /* XXX should be EREMOTEIO */
+ uipd->status = -EPIPE;
+ } else {
+ uipd->status = 0;
+ }
+ } else {
+ uipd->status = 0;
+ }
uipd->actual_length = xfer->frlengths[x];
- uipd->status = 0;
if (!xfer->flags.ext_buffer) {
usbd_copy_out(xfer->frbuffers, offset,
USB_ADD_BYTES(urb->transfer_buffer,
@@ -1385,8 +1395,8 @@ usb_linux_isoc_callback(struct usb_xfer
if (xfer->actlen < xfer->sumlen) {
/* short transfer */
if (urb->transfer_flags & URB_SHORT_NOT_OK) {
- urb->status = -EPIPE; /* XXX should be
- * EREMOTEIO */
+ /* XXX should be EREMOTEIO */
+ urb->status = -EPIPE;
} else {
urb->status = 0;
}
@@ -1482,6 +1492,7 @@ tr_setup:
/* Set zero for "actual_length" */
for (x = 0; x < urb->number_of_packets; x++) {
urb->iso_frame_desc[x].actual_length = 0;
+ urb->iso_frame_desc[x].status = urb->status;
}
/* call callback */
@@ -1663,3 +1674,58 @@ setup_bulk:
goto tr_setup;
}
}
+
+/*------------------------------------------------------------------------*
+ * usb_fill_bulk_urb
+ *------------------------------------------------------------------------*/
+void
+usb_fill_bulk_urb(struct urb *urb, struct usb_device *udev,
+ struct usb_host_endpoint *uhe, void *buf,
+ int length, usb_complete_t callback, void *arg)
+{
+ urb->dev = udev;
+ urb->endpoint = uhe;
+ urb->transfer_buffer = buf;
+ urb->transfer_buffer_length = length;
+ urb->complete = callback;
+ urb->context = arg;
+}
+
+/*------------------------------------------------------------------------*
+ * usb_bulk_msg
+ *
+ * NOTE: This function can also be used for interrupt endpoints!
+ *
+ * Return values:
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+int
+usb_bulk_msg(struct usb_device *udev, struct usb_host_endpoint *uhe,
+ void *data, int len, uint16_t *pactlen, usb_timeout_t timeout)
+{
+ struct urb *urb;
+ int err;
+
+ if (uhe == NULL)
+ return (-EINVAL);
+ if (len < 0)
+ return (-EINVAL);
+
+ err = usb_setup_endpoint(udev, uhe, 4096 /* bytes */);
+ if (err)
+ return (err);
+
+ urb = usb_alloc_urb(0, 0);
+ if (urb == NULL)
+ return (-ENOMEM);
+
+ usb_fill_bulk_urb(urb, udev, uhe, data, len,
+ usb_linux_wait_complete, NULL);
+
+ err = usb_start_wait_urb(urb, timeout, pactlen);
+
+ usb_free_urb(urb);
+
+ return (err);
+}
Modified: stable/8/sys/dev/usb/usb_compat_linux.h
==============================================================================
--- stable/8/sys/dev/usb/usb_compat_linux.h Wed Dec 9 22:31:45 2009 (r200322)
+++ stable/8/sys/dev/usb/usb_compat_linux.h Wed Dec 9 22:32:36 2009 (r200323)
@@ -217,7 +217,7 @@ struct usb_iso_packet_descriptor {
* packets are usually back to back) */
uint16_t length; /* expected length */
uint16_t actual_length;
- uint16_t status;
+ int16_t status; /* transfer status */
};
/*
@@ -299,6 +299,11 @@ void usb_set_intfdata(struct usb_interfa
void usb_linux_register(void *arg);
void usb_linux_deregister(void *arg);
+void usb_fill_bulk_urb(struct urb *, struct usb_device *,
+ struct usb_host_endpoint *, void *, int, usb_complete_t, void *);
+int usb_bulk_msg(struct usb_device *, struct usb_host_endpoint *,
+ void *, int, uint16_t *, usb_timeout_t);
+
#define interface_to_usbdev(intf) (intf)->linux_udev
#define interface_to_bsddev(intf) (intf)->linux_udev
More information about the svn-src-stable
mailing list