ChangeSet 1.1243.50.12, 2003/06/10 14:49:35-07:00, stern@rowland.harvard.edu

[PATCH] USB: Make hub.c DMA-aware

This patch makes the hub status irq DMA-aware, by pre-allocating the
transfer buffer in consistent memory.  Unfortunately, there doesn't seem
to be an easy way to do the same for the status report buffers.


 drivers/usb/core/hub.c |   11 ++++++++---
 drivers/usb/core/hub.h |    1 +
 2 files changed, 9 insertions(+), 3 deletions(-)


diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	Tue Jun 10 17:11:23 2003
+++ b/drivers/usb/core/hub.c	Tue Jun 10 17:11:23 2003
@@ -302,9 +302,10 @@
 	int maxp, ret;
 	char *message;
 
-	hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);
+	hub->buffer = usb_buffer_alloc(dev, sizeof(*hub->buffer), GFP_KERNEL,
+			&hub->buffer_dma);
 	if (!hub->buffer) {
-		message = "can't kmalloc hub irq buffer";
+		message = "can't allocate hub irq buffer";
 		ret = -ENOMEM;
 		goto fail;
 	}
@@ -459,6 +460,8 @@
 
 	usb_fill_int_urb(hub->urb, dev, pipe, *hub->buffer, maxp, hub_irq,
 		hub, endpoint->bInterval);
+	hub->urb->transfer_dma = hub->buffer_dma;
+	hub->urb->transfer_flags |= URB_NO_DMA_MAP;
 	ret = usb_submit_urb(hub->urb, GFP_KERNEL);
 	if (ret) {
 		message = "couldn't submit status urb";
@@ -522,7 +525,9 @@
 	}
 
 	if (hub->buffer) {
-		kfree(hub->buffer);
+		usb_buffer_free(interface_to_usbdev(intf),
+				sizeof(*hub->buffer), hub->buffer,
+				hub->buffer_dma);
 		hub->buffer = NULL;
 	}
 
diff -Nru a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
--- a/drivers/usb/core/hub.h	Tue Jun 10 17:11:23 2003
+++ b/drivers/usb/core/hub.h	Tue Jun 10 17:11:23 2003
@@ -175,6 +175,7 @@
 
 	/* buffer for urb ... 1 bit each for hub and children, rounded up */
 	char			(*buffer)[(USB_MAXCHILDREN + 1 + 7) / 8];
+	dma_addr_t		buffer_dma;	/* DMA address for buffer */
 	union {
 		struct usb_hub_status	hub;
 		struct usb_port_status	port;
