<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># 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.686   -&gt; 1.687  
#	   drivers/usb/hcd.h	1.3     -&gt; 1.4    
#	   drivers/usb/hcd.c	1.5     -&gt; 1.6    
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/26	david-b@pacbell.net	1.687
# [PATCH] Re: [PATCH 2.4.20-pre7 1 of 2] usbcore/hcd updates
# 
# Here's the first of those two patches, to usbcore's "hcd" glue:
# 
#  - removes something I left in pre7 to simplify these patches.
#  - does pci map/unmap for the hardware-aware layer
#  - knows that none fault mode is no longer allowed
# --------------------------------------------
#
diff -Nru a/drivers/usb/hcd.c b/drivers/usb/hcd.c
--- a/drivers/usb/hcd.c	Mon Sep 30 10:47:15 2002
+++ b/drivers/usb/hcd.c	Mon Sep 30 10:47:15 2002
@@ -296,7 +296,7 @@
 
 	// serial number
 	} else if (id == 1) {
-		strcpy (buf, hcd-&gt;bus_name);
+		strcpy (buf, hcd-&gt;bus-&gt;bus_name);
 
 	// product description
 	} else if (id == 2) {
@@ -392,7 +392,7 @@
 	case DeviceOutRequest | USB_REQ_SET_ADDRESS:
 		// wValue == urb-&gt;dev-&gt;devaddr
 		dbg ("%s root hub device address %d",
-			hcd-&gt;bus_name, wValue);
+			hcd-&gt;bus-&gt;bus_name, wValue);
 		break;
 
 	/* INTERFACE REQUESTS (no defined feature/status flags) */
@@ -506,7 +506,7 @@
 					&amp;&amp; rh_status_urb (hcd, urb) != 0) {
 				/* another driver snuck in? */
 				dbg ("%s, can't resubmit roothub status urb?",
-					hcd-&gt;bus_name);
+					hcd-&gt;bus-&gt;bus_name);
 				spin_unlock_irqrestore (&amp;hcd_data_lock, flags);
 				BUG ();
 			}
@@ -687,6 +687,7 @@
 		base);
 
 // FIXME simpler: make "bus" be that data, not pointer to it.
+// (fixed in 2.5)
 	bus = usb_alloc_bus (&amp;hcd_operations);
 	if (bus == NULL) {
 		dbg ("usb_alloc_bus fail");
@@ -695,7 +696,6 @@
 		goto clean_3;
 	}
 	hcd-&gt;bus = bus;
-	hcd-&gt;bus_name = dev-&gt;slot_name;		/* prefer bus-&gt;bus_name */
 	bus-&gt;bus_name = dev-&gt;slot_name;
 	hcd-&gt;product_desc = dev-&gt;name;
 	bus-&gt;hcpriv = (void *) hcd;
@@ -739,14 +739,14 @@
 	hcd = pci_get_drvdata(dev);
 	if (!hcd)
 		return;
-	info ("remove: %s, state %x", hcd-&gt;bus_name, hcd-&gt;state);
+	info ("remove: %s, state %x", hcd-&gt;bus-&gt;bus_name, hcd-&gt;state);
 
 	if (in_interrupt ()) BUG ();
 
 	hub = hcd-&gt;bus-&gt;root_hub;
 	hcd-&gt;state = USB_STATE_QUIESCING;
 
-	dbg ("%s: roothub graceful disconnect", hcd-&gt;bus_name);
+	dbg ("%s: roothub graceful disconnect", hcd-&gt;bus-&gt;bus_name);
 	usb_disconnect (&amp;hub);
 	// usb_disconnect (&amp;hcd-&gt;bus-&gt;root_hub);
 
@@ -817,7 +817,7 @@
 	int			retval;
 
 	hcd = pci_get_drvdata(dev);
-	info ("suspend %s to state %d", hcd-&gt;bus_name, state);
+	info ("suspend %s to state %d", hcd-&gt;bus-&gt;bus_name, state);
 
 	pci_save_state (dev, hcd-&gt;pci_state);
 
@@ -846,12 +846,12 @@
 	int			retval;
 
 	hcd = pci_get_drvdata(dev);
-	info ("resume %s", hcd-&gt;bus_name);
+	info ("resume %s", hcd-&gt;bus-&gt;bus_name);
 
 	/* guard against multiple resumes (APM bug?) */
 	atomic_inc (&amp;hcd-&gt;resume_count);
 	if (atomic_read (&amp;hcd-&gt;resume_count) != 1) {
-		err ("concurrent PCI resumes for %s", hcd-&gt;bus_name);
+		err ("concurrent PCI resumes for %s", hcd-&gt;bus-&gt;bus_name);
 		retval = 0;
 		goto done;
 	}
@@ -868,7 +868,8 @@
 
 	retval = hcd-&gt;driver-&gt;resume (hcd);
 	if (!HCD_IS_RUNNING (hcd-&gt;state)) {
-		dbg ("resume %s failure, retval %d", hcd-&gt;bus_name, retval);
+		dbg ("resume %s failure, retval %d",
+			hcd-&gt;bus-&gt;bus_name, retval);
 		hc_died (hcd);
 // FIXME:  recover, reset etc.
 	} else {
@@ -943,7 +944,8 @@
 		list_for_each (urblist, &amp;dev-&gt;urb_list) {
 			urb = list_entry (urblist, struct urb, urb_list);
 			dbg ("shutdown %s urb %p pipe %x, current status %d",
-				hcd-&gt;bus_name, urb, urb-&gt;pipe, urb-&gt;status);
+				hcd-&gt;bus-&gt;bus_name,
+				urb, urb-&gt;pipe, urb-&gt;status);
 			if (urb-&gt;status == -EINPROGRESS)
 				urb-&gt;status = -ESHUTDOWN;
 		}
@@ -1067,8 +1069,6 @@
 	if (urb-&gt;transfer_buffer_length &lt; 0)
 		return -EINVAL;
 
-	// FIXME set urb-&gt;transfer_dma and/or setup_dma 
-
 	if (urb-&gt;next) {
 		warn ("use explicit queuing not urb-&gt;next");
 		return -EINVAL;
@@ -1186,16 +1186,26 @@
 	if (status)
 		return status;
 
+	// NOTE:  2.5 does this if !URB_NO_DMA_MAP transfer flag
+	if (usb_pipecontrol (urb-&gt;pipe))
+		urb-&gt;setup_dma = pci_map_single (
+				hcd-&gt;pdev,
+				urb-&gt;setup_packet,
+				sizeof (struct usb_ctrlrequest),
+				PCI_DMA_TODEVICE);
+	if (urb-&gt;transfer_buffer_length != 0)
+		urb-&gt;transfer_dma = pci_map_single (
+				hcd-&gt;pdev,
+				urb-&gt;transfer_buffer,
+				urb-&gt;transfer_buffer_length,
+				usb_pipein (urb-&gt;pipe)
+				    ? PCI_DMA_FROMDEVICE
+				    : PCI_DMA_TODEVICE);
+
 	if (urb-&gt;dev == hcd-&gt;bus-&gt;root_hub)
 		status = rh_urb_enqueue (hcd, urb);
 	else
 		status = hcd-&gt;driver-&gt;urb_enqueue (hcd, urb, mem_flags);
-	/* urb-&gt;dev got nulled if hcd called giveback for us
-	 * NOTE: ref to urb-&gt;dev is a race without (2.5) refcounting,
-	 * unless driver only returns status when it didn't giveback 
-	 */
-	if (status &amp;&amp; urb-&gt;dev)
-		urb_unlink (urb);
 	return status;
 }
 
@@ -1282,25 +1292,25 @@
 		goto done;
 	}
 
-	/* For non-periodic transfers, any status except -EINPROGRESS means
-	 * the HCD has already started to unlink this URB from the hardware.
-	 * In that case, there's no more work to do.
+	/* Any status except -EINPROGRESS means the HCD has already started
+	 * to return this URB to the driver.  In that case, there's no
+	 * more work for us to do.
 	 *
-	 * For periodic transfers, this is the only way to trigger unlinking
-	 * from the hardware.  Since we (currently) overload urb-&gt;status to
-	 * tell the driver to unlink, error status might get clobbered ...
-	 * unless that transfer hasn't yet restarted.  One such case is when
-	 * the URB gets unlinked from its completion handler.
+	 * There's much magic because of "automagic resubmit" of interrupt
+	 * transfers, stopped only by explicit unlinking.  We won't issue
+	 * an "it's unlinked" callback more than once, but device drivers
+	 * can need to retry (SMP, -EAGAIN) an unlink request as well as
+	 * fake out the "not yet completed" state (set -EINPROGRESS) if
+	 * unlinking from complete().  Automagic eventually vanishes.
 	 *
 	 * FIXME use an URB_UNLINKED flag to match URB_TIMEOUT_KILLED
 	 */
-	switch (usb_pipetype (urb-&gt;pipe)) {
-	case PIPE_CONTROL:
-	case PIPE_BULK:
-		if (urb-&gt;status != -EINPROGRESS) {
+	if (urb-&gt;status != -EINPROGRESS) {
+		if (usb_pipetype (urb-&gt;pipe) == PIPE_INTERRUPT)
+			retval = -EAGAIN;
+		else
 			retval = -EINVAL;
-			goto done;
-		}
+		goto done;
 	}
 
 	/* maybe set up to block on completion notification */
@@ -1340,7 +1350,7 @@
 			&amp;&amp; HCD_IS_RUNNING (hcd-&gt;state)
 			&amp;&amp; !retval) {
 		dbg ("%s: wait for giveback urb %p",
-			hcd-&gt;bus_name, urb);
+			hcd-&gt;bus-&gt;bus_name, urb);
 		wait_for_completion (&amp;splice.done);
 	} else if ((urb-&gt;transfer_flags &amp; USB_ASYNC_UNLINK) &amp;&amp; retval == 0) {
 		return -EINPROGRESS;
@@ -1352,7 +1362,7 @@
 bye:
 	if (retval)
 		dbg ("%s: hcd_unlink_urb fail %d",
-		    hcd ? hcd-&gt;bus_name : "(no bus?)",
+		    hcd ? hcd-&gt;bus-&gt;bus_name : "(no bus?)",
 		    retval);
 	return retval;
 }
@@ -1385,7 +1395,7 @@
 	/* device driver problem with refcounts? */
 	if (!list_empty (&amp;dev-&gt;urb_list)) {
 		dbg ("free busy dev, %s devnum %d (bug!)",
-			hcd-&gt;bus_name, udev-&gt;devnum);
+			hcd-&gt;bus-&gt;bus_name, udev-&gt;devnum);
 		return -EINVAL;
 	}
 
@@ -1460,7 +1470,17 @@
 		dbg ("giveback urb %p status %d len %d",
 			urb, urb-&gt;status, urb-&gt;actual_length);
 
-	// FIXME unmap urb-&gt;transfer_dma and/or setup_dma 
+	// NOTE:  2.5 does this if !URB_NO_DMA_MAP transfer flag
+	if (usb_pipecontrol (urb-&gt;pipe))
+		pci_unmap_single (hcd-&gt;pdev, urb-&gt;setup_dma,
+				sizeof (struct usb_ctrlrequest),
+				PCI_DMA_TODEVICE);
+	if (urb-&gt;transfer_buffer_length != 0)
+		pci_unmap_single (hcd-&gt;pdev, urb-&gt;transfer_dma,
+				urb-&gt;transfer_buffer_length,
+				usb_pipein (urb-&gt;pipe)
+				    ? PCI_DMA_FROMDEVICE
+				    : PCI_DMA_TODEVICE);
 
 	/* pass ownership to the completion handler */
 	urb-&gt;complete (urb);
diff -Nru a/drivers/usb/hcd.h b/drivers/usb/hcd.h
--- a/drivers/usb/hcd.h	Mon Sep 30 10:47:15 2002
+++ b/drivers/usb/hcd.h	Mon Sep 30 10:47:15 2002
@@ -36,7 +36,6 @@
 	struct usb_bus		*bus;		/* hcd is-a bus */
 	struct list_head	hcd_list;
 
-	const char		*bus_name;
 	const char		*product_desc;
 	const char		*description;	/* "ehci-hcd" etc */
 
</pre></body></html>