# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.474.2.4 -> 1.474.2.5
#	drivers/usb/core/hcd.c	1.29    -> 1.30   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/08/13	david-b@pacbell.net	1.474.2.5
# [PATCH] HCDs support new DMA APIs (part 2 of 2)
# 
# - teaches the shared "hcd" code to set urb->*_dma whenever the device
#   driver didn't, by creating singleshot mappings.
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c	Tue Aug 13 15:34:03 2002
+++ b/drivers/usb/core/hcd.c	Tue Aug 13 15:34:03 2002
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/uts.h>			/* for UTS_SYSNAME */
+#include <linux/pci.h>			/* for hcd->pdev and dma addressing */
 #include <asm/byteorder.h>
 
 
@@ -1021,6 +1022,24 @@
 	if (status)
 		return status;
 
+	/* lower level hcd code should use *_dma exclusively */
+	if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
+		if (usb_pipecontrol (urb->pipe))
+			urb->setup_dma = pci_map_single (
+					hcd->pdev,
+					urb->setup_packet,
+					sizeof (struct usb_ctrlrequest),
+					PCI_DMA_TODEVICE);
+		if (urb->transfer_buffer_length != 0)
+			urb->transfer_dma = pci_map_single (
+					hcd->pdev,
+					urb->transfer_buffer,
+					urb->transfer_buffer_length,
+					usb_pipein (urb->pipe)
+					    ? PCI_DMA_FROMDEVICE
+					    : PCI_DMA_TODEVICE);
+	}
+
 	/* increment urb's reference count as part of giving it to the HCD
 	 * (which now controls it).  HCD guarantees that it either returns
 	 * an error or calls giveback(), but not both.
@@ -1288,6 +1307,20 @@
 	if (urb->status)
 		dbg ("giveback urb %p status %d len %d",
 			urb, urb->status, urb->actual_length);
+
+	/* lower level hcd code should use *_dma exclusively */
+	if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
+		if (usb_pipecontrol (urb->pipe))
+			pci_unmap_single (hcd->pdev, urb->setup_dma,
+					sizeof (struct usb_ctrlrequest),
+					PCI_DMA_TODEVICE);
+		if (urb->transfer_buffer_length != 0)
+			pci_unmap_single (hcd->pdev, urb->transfer_dma,
+					urb->transfer_buffer_length,
+					usb_pipein (urb->pipe)
+					    ? PCI_DMA_FROMDEVICE
+					    : PCI_DMA_TODEVICE);
+	}
 
 	/* pass ownership to the completion handler */
 	urb->complete (urb);
