PERFORCE change 130003 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sun Dec 2 04:00:53 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=130003
Change 130003 by hselasky at hselasky_laptop001 on 2007/12/02 12:00:36
Enable zero-copy for the Linux USB API by default.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.c#13 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.c#13 (text+ko) ====
@@ -761,6 +761,16 @@
cfg[0].bufsize = 0; /* use wMaxPacketSize */
cfg[0].frames = usb_max_isoc_frames(dev);
cfg[0].flags.proxy_buffer = 1;
+#if 0
+ /*
+ * The Linux USB API allows non back-to-back
+ * isochronous frames which we do not support. If the
+ * isochronous frames are not back-to-back we need to
+ * do a copy, and then we need a buffer for
+ * that. Enable this at your own risk.
+ */
+ cfg[0].flags.ext_buffer = 1;
+#endif
cfg[0].flags.short_xfer_ok = 1;
bcopy(cfg + 0, cfg + 1, sizeof(*cfg));
@@ -768,8 +778,7 @@
/* Allocate and setup two generic FreeBSD USB transfers */
if (usbd_transfer_setup(dev->bsd_udev, uhe->bsd_iface_index,
- uhe->bsd_xfer, cfg, 2, uhe,
- &usb_global_lock)) {
+ uhe->bsd_xfer, cfg, 2, uhe, &usb_global_lock)) {
return -EINVAL;
}
} else {
@@ -784,12 +793,12 @@
cfg[0].direction = addr & (UE_DIR_OUT | UE_DIR_IN);
cfg[0].callback = &usb_linux_non_isoc_callback;
cfg[0].bufsize = bufsize;
+ cfg[0].flags.ext_buffer = 1; /* enable zero-copy */
cfg[0].flags.proxy_buffer = 1;
cfg[0].flags.short_xfer_ok = 1;
if (usbd_transfer_setup(dev->bsd_udev, uhe->bsd_iface_index,
- uhe->bsd_xfer, cfg, 1, uhe,
- &usb_global_lock)) {
+ uhe->bsd_xfer, cfg, 1, uhe, &usb_global_lock)) {
return -EINVAL;
}
}
@@ -1286,9 +1295,11 @@
uipd = urb->iso_frame_desc + x;
uipd->actual_length = xfer->frlengths[x];
uipd->status = 0;
- usbd_copy_out(xfer->frbuffers + 0, offset,
- ((uint8_t *)(urb->transfer_buffer)) + uipd->offset,
- uipd->actual_length);
+ if (!xfer->flags.ext_buffer) {
+ usbd_copy_out(xfer->frbuffers + 0, offset,
+ USBD_ADD_BYTES(urb->transfer_buffer,
+ uipd->offset), uipd->actual_length);
+ }
offset += max_frame;
}
} else {
@@ -1354,9 +1365,11 @@
for (x = 0; x < urb->number_of_packets; x++) {
uipd = urb->iso_frame_desc + x;
xfer->frlengths[x] = uipd->length;
- usbd_copy_in(xfer->frbuffers + 0, offset,
- ((uint8_t *)(urb->transfer_buffer)) + uipd->offset,
- uipd->length);
+ if (!xfer->flags.ext_buffer) {
+ usbd_copy_in(xfer->frbuffers + 0, offset,
+ USBD_ADD_BYTES(urb->transfer_buffer,
+ uipd->offset), uipd->length);
+ }
offset += uipd->length;
}
} else {
@@ -1376,6 +1389,11 @@
}
}
+ if (xfer->flags.ext_buffer) {
+ /* set virtual address to load */
+ usbd_set_frame_data(xfer,
+ urb->transfer_buffer, 0);
+ }
xfer->priv_fifo = urb;
xfer->flags.force_short_xfer = 0;
xfer->timeout = urb->timeout;
@@ -1441,7 +1459,7 @@
xfer->frlengths[0] = 0;
}
- if (urb->bsd_isread) {
+ if (urb->bsd_isread && (!xfer->flags.ext_buffer)) {
/* copy in data with regard to the URB */
usbd_copy_out(xfer->frbuffers + data_frame, 0,
urb->bsd_data_ptr, xfer->frlengths[data_frame]);
@@ -1495,8 +1513,14 @@
* USB control transfers need special handling.
* First copy in the header, then copy in data!
*/
- usbd_copy_in(xfer->frbuffers + 0, 0,
- urb->setup_packet, REQ_SIZE);
+ if (!xfer->flags.ext_buffer) {
+ usbd_copy_in(xfer->frbuffers + 0, 0,
+ urb->setup_packet, REQ_SIZE);
+ } else {
+ /* set virtual address to load */
+ usbd_set_frame_data(xfer,
+ urb->setup_packet, 0);
+ }
xfer->frlengths[0] = REQ_SIZE;
@@ -1528,7 +1552,11 @@
}
/* check if we need to copy in data */
- if (!(urb->bsd_isread)) {
+ if (xfer->flags.ext_buffer) {
+ /* set virtual address to load */
+ usbd_set_frame_data(xfer, urb->bsd_data_ptr,
+ data_frame);
+ } else if (!urb->bsd_isread) {
/* copy out data with regard to the URB */
usbd_copy_in(xfer->frbuffers + data_frame, 0,
urb->bsd_data_ptr, max_bulk);
More information about the p4-projects
mailing list