Commit 2193b1ea authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

usb host controllers:

	- add mem_flags support
	- portions of this patch by Oliver Neukum and David Brownell.
parent a707e953
......@@ -916,14 +916,13 @@ static void hc_died (struct usb_hcd *hcd)
/* 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 @@ static int hcd_submit_urb (struct urb *urb)
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 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb)
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;
......
......@@ -1476,7 +1476,7 @@ static struct urb *uhci_find_urb_ep(struct uhci *uhci, struct urb *urb)
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 @@ static int uhci_get_current_frame_number(struct usb_device *dev)
}
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 @@ static void uhci_call_completion(struct urb *urb)
} 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 */
......
......@@ -532,7 +532,7 @@ static int sohci_return_urb (struct ohci *hc, struct urb * urb)
/* 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 @@ static int sohci_submit_urb (struct urb * urb)
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 @@ static int sohci_submit_urb (struct urb * urb)
}
/* 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 @@ static int sohci_get_current_frame_number (struct usb_device *usb_dev)
/*-------------------------------------------------------------------------*/
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,
};
/*-------------------------------------------------------------------------*
......
......@@ -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 @@ _static int uhci_submit_int_urb (struct urb *urb)
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 @@ _static int uhci_submit_iso_urb (struct urb *urb)
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 @@ _static struct urb* search_dev_ep (uhci_t *s, struct urb *urb)
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 @@ _static int uhci_submit_urb (struct urb *urb)
#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 @@ _static int uhci_submit_urb (struct urb *urb)
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 @@ _static int uhci_get_current_frame_number (struct usb_device *usb_dev)
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 @@ _static int process_urb (uhci_t *s, struct list_head *p)
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 @@ _static int process_urb (uhci_t *s, struct list_head *p)
// 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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment