# 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.220.2.1 -> 1.220.2.2
#	   drivers/usb/hcd.c	1.7     -> 1.8    
#	drivers/usb/usb-ohci.c	1.22    -> 1.23   
#	  drivers/usb/uhci.c	1.21    -> 1.22   
#	drivers/usb/usb-uhci.c	1.23    -> 1.24   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/02/06	greg@soap.kroah.net	1.220.2.2
# usb host controllers:
# 	- add mem_flags support
# 	- portions of this patch by Oliver Neukum and David Brownell.
# --------------------------------------------
#
diff -Nru a/drivers/usb/hcd.c b/drivers/usb/hcd.c
--- a/drivers/usb/hcd.c	Wed Feb  6 20:47:55 2002
+++ b/drivers/usb/hcd.c	Wed Feb  6 20:47:55 2002
@@ -916,14 +916,13 @@
 /* may be called in any context with a valid urb->dev usecount */
 /* caller surrenders "ownership" of urb (and chain at urb->next).  */
 
-static int hcd_submit_urb (struct urb *urb)
+static int hcd_submit_urb (struct urb *urb, int mem_flags)
 {
 	int			status;
 	struct usb_hcd		*hcd;
 	struct hcd_dev		*dev;
 	unsigned long		flags;
 	int			pipe;
-	int			mem_flags;
 
 	if (!urb || urb->hcpriv || !urb->complete)
 		return -EINVAL;
@@ -947,11 +946,6 @@
 			usb_pipeout (pipe)))
 		return -EPIPE;
 
-	// FIXME paging/swapping requests over USB should not use GFP_KERNEL
-	// and might even need to use GFP_NOIO ... that flag actually needs
-	// to be passed from the higher level.
-	mem_flags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL;
-
 #ifdef DEBUG
 	{
 	unsigned int	orig_flags = urb->transfer_flags;
@@ -1316,7 +1310,7 @@
 	else if (urb->next) {
 		int 	status;
 
-		status = usb_submit_urb (urb->next);
+		status = usb_submit_urb (urb->next, GFP_ATOMIC);
 		if (status) {
 			dbg ("urb %p chain fail, %d", urb->next, status);
 			urb->next->status = -ENOTCONN;
diff -Nru a/drivers/usb/uhci.c b/drivers/usb/uhci.c
--- a/drivers/usb/uhci.c	Wed Feb  6 20:47:55 2002
+++ b/drivers/usb/uhci.c	Wed Feb  6 20:47:55 2002
@@ -1476,7 +1476,7 @@
 	return u;
 }
 
-static int uhci_submit_urb(struct urb *urb)
+static int uhci_submit_urb(struct urb *urb, int mem_flags)
 {
 	int ret = -EINVAL;
 	struct uhci *uhci;
@@ -1823,11 +1823,11 @@
 }
 
 struct usb_operations uhci_device_operations = {
-	uhci_alloc_dev,
-	uhci_free_dev,
-	uhci_get_current_frame_number,
-	uhci_submit_urb,
-	uhci_unlink_urb
+	allocate:		uhci_alloc_dev,
+	deallocate:		uhci_free_dev,
+	get_frame_number:	uhci_get_current_frame_number,
+	submit_urb:		uhci_submit_urb,
+	unlink_urb:		uhci_unlink_urb,
 };
 
 /* Virtual Root Hub */
@@ -2294,7 +2294,7 @@
 	} else {
 		if (is_ring && !killed) {
 			urb->dev = dev;
-			uhci_submit_urb(urb);
+			uhci_submit_urb(urb, GFP_KERNEL);
 		} else {
 			/* We decrement the usage count after we're done */
 			/*  with everything */
diff -Nru a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c
--- a/drivers/usb/usb-ohci.c	Wed Feb  6 20:47:55 2002
+++ b/drivers/usb/usb-ohci.c	Wed Feb  6 20:47:55 2002
@@ -532,7 +532,7 @@
 
 /* get a transfer request */
  
-static int sohci_submit_urb (struct urb * urb)
+static int sohci_submit_urb (struct urb * urb, int mem_flags)
 {
 	ohci_t * ohci;
 	ed_t * ed;
@@ -542,7 +542,6 @@
 	int i, size = 0;
 	unsigned long flags;
 	int bustime = 0;
-	int mem_flags = ALLOC_FLAGS;
 	
 	if (!urb->dev || !urb->dev->bus)
 		return -ENODEV;
@@ -612,8 +611,7 @@
 	}
 
 	/* allocate the private part of the URB */
-	urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), 
-							in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+	urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), mem_flags);
 	if (!urb_priv) {
 		usb_dec_dev_use (urb->dev);	
 		return -ENOMEM;
@@ -919,11 +917,11 @@
 /*-------------------------------------------------------------------------*/
 
 struct usb_operations sohci_device_operations = {
-	sohci_alloc_dev,
-	sohci_free_dev,
-	sohci_get_current_frame_number,
-	sohci_submit_urb,
-	sohci_unlink_urb
+	allocate:		sohci_alloc_dev,
+	deallocate:		sohci_free_dev,
+	get_frame_number:	sohci_get_current_frame_number,
+	submit_urb:		sohci_submit_urb,
+	unlink_urb:		sohci_unlink_urb,
 };
 
 /*-------------------------------------------------------------------------*
diff -Nru a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c
--- a/drivers/usb/usb-uhci.c	Wed Feb  6 20:47:55 2002
+++ b/drivers/usb/usb-uhci.c	Wed Feb  6 20:47:55 2002
@@ -87,7 +87,6 @@
 #endif
 
 #define SLAB_FLAG     (in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL)
-#define KMALLOC_FLAG  (in_interrupt ()? GFP_ATOMIC : GFP_KERNEL)
 
 /* CONFIG_USB_UHCI_HIGH_BANDWITH turns on Full Speed Bandwidth
  * Reclamation: feature that puts loop on descriptor loop when
@@ -1502,7 +1501,7 @@
 	return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int uhci_submit_iso_urb (struct urb *urb)
+_static int uhci_submit_iso_urb (struct urb *urb, int mem_flags)
 {
 	uhci_t *s = (uhci_t*) urb->dev->bus->hcpriv;
 	urb_priv_t *urb_priv = urb->hcpriv;
@@ -1522,7 +1521,7 @@
 	if (ret)
 		goto err;
 
-	tdm = (uhci_desc_t **) kmalloc (urb->number_of_packets * sizeof (uhci_desc_t*), KMALLOC_FLAG);
+	tdm = (uhci_desc_t **) kmalloc (urb->number_of_packets * sizeof (uhci_desc_t*), mem_flags);
 
 	if (!tdm) {
 		ret = -ENOMEM;
@@ -1619,7 +1618,7 @@
 	return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int uhci_submit_urb (struct urb *urb)
+_static int uhci_submit_urb (struct urb *urb, int mem_flags)
 {
 	uhci_t *s;
 	urb_priv_t *urb_priv;
@@ -1676,7 +1675,7 @@
 #ifdef DEBUG_SLAB
 	urb_priv = kmem_cache_alloc(urb_priv_kmem, SLAB_FLAG);
 #else
-	urb_priv = kmalloc (sizeof (urb_priv_t), KMALLOC_FLAG);
+	urb_priv = kmalloc (sizeof (urb_priv_t), mem_flags);
 #endif
 	if (!urb_priv) {
 		usb_dec_dev_use (urb->dev);
@@ -1729,12 +1728,12 @@
 				if (bustime < 0) 
 					ret = bustime;
 				else {
-					ret = uhci_submit_iso_urb(urb);
+					ret = uhci_submit_iso_urb(urb, mem_flags);
 					if (ret == 0)
 						usb_claim_bandwidth (urb->dev, urb, bustime, 1);
 				}
 			} else {        /* bandwidth is already set */
-				ret = uhci_submit_iso_urb(urb);
+				ret = uhci_submit_iso_urb(urb, mem_flags);
 			}
 			break;
 		case PIPE_INTERRUPT:
@@ -2279,11 +2278,11 @@
 
 struct usb_operations uhci_device_operations =
 {
-	uhci_alloc_dev,
-	uhci_free_dev,
-	uhci_get_current_frame_number,
-	uhci_submit_urb,
-	uhci_unlink_urb
+	allocate:		uhci_alloc_dev,
+	deallocate:		uhci_free_dev,
+	get_frame_number:	uhci_get_current_frame_number,
+	submit_urb:		uhci_submit_urb,
+	unlink_urb:		uhci_unlink_urb,
 };
 
 _static void correct_data_toggles(struct urb *urb)
@@ -2697,7 +2696,10 @@
 
 						spin_unlock(&s->urb_list_lock);
 
-						ret_submit=uhci_submit_urb(next_urb);
+						// FIXME!!!
+						// We need to know the real state, so 
+						// GFP_ATOMIC is probably not correct
+						ret_submit=uhci_submit_urb(next_urb, GFP_ATOMIC);
 						spin_lock(&s->urb_list_lock);
 						
 						if (ret_submit)
@@ -2721,7 +2723,10 @@
 				// Re-submit the URB if ring-linked
 				if (is_ring && !was_unlinked && !contains_killed) {
 					urb->dev=usb_dev;
-					uhci_submit_urb (urb);
+					// FIXME!!!
+					// We need to know the real state, so 
+					// GFP_ATOMIC is probably not correct
+					uhci_submit_urb (urb, GFP_ATOMIC);
 				}
 				spin_lock(&s->urb_list_lock);
 			}
