diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-29 10:30:05 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-29 10:30:05 -0700 |
| commit | b961f5b44d697115d75b92dd17180434918f9a51 (patch) | |
| tree | 897ddde26706778c2172703dea2c6f32b86074a7 /usb.current | |
| parent | 45250a2845d53761aa4ad162ff76a1747f451d9c (diff) | |
| download | patches-b961f5b44d697115d75b92dd17180434918f9a51.tar.gz | |
sync up with Linux for 2.6.34-rc2
Deleted all of the patches that went into Linus's tree
Diffstat (limited to 'usb.current')
45 files changed, 0 insertions, 6326 deletions
diff --git a/usb.current/usb-cdc-acm-fix-stupid-null-pointer-in-resume.patch b/usb.current/usb-cdc-acm-fix-stupid-null-pointer-in-resume.patch deleted file mode 100644 index 61357bc135c715..00000000000000 --- a/usb.current/usb-cdc-acm-fix-stupid-null-pointer-in-resume.patch +++ /dev/null @@ -1,30 +0,0 @@ -From oliver@neukum.org Mon Mar 15 13:32:58 2010 -From: Oliver Neukum <oliver@neukum.org> -Date: Wed, 3 Mar 2010 00:37:56 +0100 -Subject: USB: cdc-acm: Fix stupid NULL pointer in resume() -To: Greg KH <greg@kroah.com> -Cc: Rickard Bellini <rickard.bellini@ericsson.com>, linux-usb@vger.kernel.org, stable@kernel.org -Message-ID: <201003030037.56242.oliver@neukum.org> - - -Stupid logic bug passing a just nulled pointer - -Signed-off-by: Oliver Neukum <neukum@b1-systems.de> -Cc: stable <stable@kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/class/cdc-acm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/class/cdc-acm.c -+++ b/drivers/usb/class/cdc-acm.c -@@ -1441,7 +1441,7 @@ static int acm_resume(struct usb_interfa - wb = acm->delayed_wb; - acm->delayed_wb = NULL; - spin_unlock_irq(&acm->write_lock); -- acm_start_wb(acm, acm->delayed_wb); -+ acm_start_wb(acm, wb); - } else { - spin_unlock_irq(&acm->write_lock); - } diff --git a/usb.current/usb-cdc-wdm-fix-deadlock-between-write-and-resume.patch b/usb.current/usb-cdc-wdm-fix-deadlock-between-write-and-resume.patch deleted file mode 100644 index 3817249395cb8a..00000000000000 --- a/usb.current/usb-cdc-wdm-fix-deadlock-between-write-and-resume.patch +++ /dev/null @@ -1,36 +0,0 @@ -From oliver@neukum.org Mon Mar 15 16:15:34 2010 -From: Oliver Neukum <oliver@neukum.org> -Date: Sat, 27 Feb 2010 20:57:12 +0100 -Subject: usb: cdc-wdm: Fix deadlock between write and resume -To: Greg KH <greg@kroah.com> -Cc: Rickard Bellini <rickard.bellini@ericsson.com>, "linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org> -Message-ID: <201002272057.12494.oliver@neukum.org> - - -From: Oliver Neukum <oliver@neukum.org> - -The new runtime PM scheme allows resume() to have no locks. -This fixes the deadlock. - -Signed-off-by: Oliver Neukum <neukum@b1-systems.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/class/cdc-wdm.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/usb/class/cdc-wdm.c -+++ b/drivers/usb/class/cdc-wdm.c -@@ -839,10 +839,10 @@ static int wdm_resume(struct usb_interfa - int rv; - - dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); -- mutex_lock(&desc->lock); -+ - clear_bit(WDM_SUSPENDING, &desc->flags); - rv = recover_from_urb_loss(desc); -- mutex_unlock(&desc->lock); -+ - return rv; - } - #endif diff --git a/usb.current/usb-cdc-wdm-fix-loss-of-data-due-to-autosuspend.patch b/usb.current/usb-cdc-wdm-fix-loss-of-data-due-to-autosuspend.patch deleted file mode 100644 index 6543f617cf9998..00000000000000 --- a/usb.current/usb-cdc-wdm-fix-loss-of-data-due-to-autosuspend.patch +++ /dev/null @@ -1,50 +0,0 @@ -From oliver@neukum.org Mon Mar 15 16:15:00 2010 -From: Oliver Neukum <oliver@neukum.org> -Date: Sat, 27 Feb 2010 20:56:22 +0100 -Subject: usb: cdc-wdm:Fix loss of data due to autosuspend -To: Greg KH <greg@kroah.com> -Cc: Rickard Bellini <rickard.bellini@ericsson.com> -Message-ID: <201002272056.22489.oliver@neukum.org> - -From: Oliver Neukum <oliver@neukum.org> - -The guarding flag must be set and tested under spinlock -and cleared before the URBs are resubmitted in resume. - -Signed-off-by: Oliver Neukum <neukum@b1-systems.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/class/cdc-wdm.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/usb/class/cdc-wdm.c -+++ b/drivers/usb/class/cdc-wdm.c -@@ -794,14 +794,17 @@ static int wdm_suspend(struct usb_interf - dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); - - mutex_lock(&desc->lock); -+ spin_lock_irq(&desc->iuspin); - #ifdef CONFIG_PM - if ((message.event & PM_EVENT_AUTO) && - (test_bit(WDM_IN_USE, &desc->flags) - || test_bit(WDM_RESPONDING, &desc->flags))) { -+ spin_unlock_irq(&desc->iuspin); - rv = -EBUSY; - } else { - #endif - set_bit(WDM_SUSPENDING, &desc->flags); -+ spin_unlock_irq(&desc->iuspin); - cancel_work_sync(&desc->rxwork); - kill_urbs(desc); - #ifdef CONFIG_PM -@@ -831,8 +834,8 @@ static int wdm_resume(struct usb_interfa - - dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); - mutex_lock(&desc->lock); -- rv = recover_from_urb_loss(desc); - clear_bit(WDM_SUSPENDING, &desc->flags); -+ rv = recover_from_urb_loss(desc); - mutex_unlock(&desc->lock); - return rv; - } diff --git a/usb.current/usb-cdc-wdm-fix-order-in-disconnect-and-fix-locking.patch b/usb.current/usb-cdc-wdm-fix-order-in-disconnect-and-fix-locking.patch deleted file mode 100644 index fe08440239788d..00000000000000 --- a/usb.current/usb-cdc-wdm-fix-order-in-disconnect-and-fix-locking.patch +++ /dev/null @@ -1,108 +0,0 @@ -From oliver@neukum.org Mon Mar 15 16:15:18 2010 -From: Oliver Neukum <oliver@neukum.org> -Date: Sat, 27 Feb 2010 20:56:47 +0100 -Subject: usb: cdc-wdm: Fix order in disconnect and fix locking -To: Greg KH <greg@kroah.com> -Cc: Rickard Bellini <rickard.bellini@ericsson.com> -Message-ID: <201002272056.47969.oliver@neukum.org> - -From: Oliver Neukum <oliver@neukum.org> - -- as the callback can schedule work, URBs must be killed first -- if the driver causes an autoresume, the caller must handle locking - -Signed-off-by: Oliver Neukum <neukum@b1-systems.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/class/cdc-wdm.c | 25 +++++++++++++++++-------- - 1 file changed, 17 insertions(+), 8 deletions(-) - ---- a/drivers/usb/class/cdc-wdm.c -+++ b/drivers/usb/class/cdc-wdm.c -@@ -776,9 +776,9 @@ static void wdm_disconnect(struct usb_in - /* to terminate pending flushes */ - clear_bit(WDM_IN_USE, &desc->flags); - spin_unlock_irqrestore(&desc->iuspin, flags); -- cancel_work_sync(&desc->rxwork); - mutex_lock(&desc->lock); - kill_urbs(desc); -+ cancel_work_sync(&desc->rxwork); - mutex_unlock(&desc->lock); - wake_up_all(&desc->wait); - if (!desc->count) -@@ -786,6 +786,7 @@ static void wdm_disconnect(struct usb_in - mutex_unlock(&wdm_mutex); - } - -+#ifdef CONFIG_PM - static int wdm_suspend(struct usb_interface *intf, pm_message_t message) - { - struct wdm_device *desc = usb_get_intfdata(intf); -@@ -793,27 +794,30 @@ static int wdm_suspend(struct usb_interf - - dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); - -- mutex_lock(&desc->lock); -+ /* if this is an autosuspend the caller does the locking */ -+ if (!(message.event & PM_EVENT_AUTO)) -+ mutex_lock(&desc->lock); - spin_lock_irq(&desc->iuspin); --#ifdef CONFIG_PM -+ - if ((message.event & PM_EVENT_AUTO) && - (test_bit(WDM_IN_USE, &desc->flags) - || test_bit(WDM_RESPONDING, &desc->flags))) { - spin_unlock_irq(&desc->iuspin); - rv = -EBUSY; - } else { --#endif -+ - set_bit(WDM_SUSPENDING, &desc->flags); - spin_unlock_irq(&desc->iuspin); -- cancel_work_sync(&desc->rxwork); -+ /* callback submits work - order is essential */ - kill_urbs(desc); --#ifdef CONFIG_PM -+ cancel_work_sync(&desc->rxwork); - } --#endif -- mutex_unlock(&desc->lock); -+ if (!(message.event & PM_EVENT_AUTO)) -+ mutex_unlock(&desc->lock); - - return rv; - } -+#endif - - static int recover_from_urb_loss(struct wdm_device *desc) - { -@@ -827,6 +831,8 @@ static int recover_from_urb_loss(struct - } - return rv; - } -+ -+#ifdef CONFIG_PM - static int wdm_resume(struct usb_interface *intf) - { - struct wdm_device *desc = usb_get_intfdata(intf); -@@ -839,6 +845,7 @@ static int wdm_resume(struct usb_interfa - mutex_unlock(&desc->lock); - return rv; - } -+#endif - - static int wdm_pre_reset(struct usb_interface *intf) - { -@@ -862,9 +869,11 @@ static struct usb_driver wdm_driver = { - .name = "cdc_wdm", - .probe = wdm_probe, - .disconnect = wdm_disconnect, -+#ifdef CONFIG_PM - .suspend = wdm_suspend, - .resume = wdm_resume, - .reset_resume = wdm_resume, -+#endif - .pre_reset = wdm_pre_reset, - .post_reset = wdm_post_reset, - .id_table = wdm_ids, diff --git a/usb.current/usb-cdc-wdm-fix-race-between-autosuspend-and-reading-from-the-device.patch b/usb.current/usb-cdc-wdm-fix-race-between-autosuspend-and-reading-from-the-device.patch deleted file mode 100644 index 50a5454b77d209..00000000000000 --- a/usb.current/usb-cdc-wdm-fix-race-between-autosuspend-and-reading-from-the-device.patch +++ /dev/null @@ -1,91 +0,0 @@ -From oliver@neukum.org Mon Mar 15 16:14:01 2010 -From: Oliver Neukum <oliver@neukum.org> -Date: Sat, 27 Feb 2010 20:54:59 +0100 -Subject: usb: cdc-wdm: Fix race between autosuspend and reading from the device -To: Greg KH <greg@kroah.com> -Cc: Rickard Bellini <rickard.bellini@ericsson.com> -Message-ID: <201002272054.59547.oliver@neukum.org> - -From: Oliver Neukum <oliver@neukum.org> - -While an available response is read the device must not -be autosuspended. This requires a flag dedicated to that -purpose. - -Signed-off-by: Oliver Neukum <neukum@b1-systems.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/class/cdc-wdm.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - ---- a/drivers/usb/class/cdc-wdm.c -+++ b/drivers/usb/class/cdc-wdm.c -@@ -52,6 +52,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); - #define WDM_READ 4 - #define WDM_INT_STALL 5 - #define WDM_POLL_RUNNING 6 -+#define WDM_RESPONDING 7 - - - #define WDM_MAX 16 -@@ -115,21 +116,22 @@ static void wdm_in_callback(struct urb * - int status = urb->status; - - spin_lock(&desc->iuspin); -+ clear_bit(WDM_RESPONDING, &desc->flags); - - if (status) { - switch (status) { - case -ENOENT: - dev_dbg(&desc->intf->dev, - "nonzero urb status received: -ENOENT"); -- break; -+ goto skip_error; - case -ECONNRESET: - dev_dbg(&desc->intf->dev, - "nonzero urb status received: -ECONNRESET"); -- break; -+ goto skip_error; - case -ESHUTDOWN: - dev_dbg(&desc->intf->dev, - "nonzero urb status received: -ESHUTDOWN"); -- break; -+ goto skip_error; - case -EPIPE: - dev_err(&desc->intf->dev, - "nonzero urb status received: -EPIPE\n"); -@@ -145,6 +147,7 @@ static void wdm_in_callback(struct urb * - desc->reslength = urb->actual_length; - memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); - desc->length += desc->reslength; -+skip_error: - wake_up(&desc->wait); - - set_bit(WDM_READ, &desc->flags); -@@ -227,6 +230,7 @@ static void wdm_int_callback(struct urb - desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - spin_lock(&desc->iuspin); - clear_bit(WDM_READ, &desc->flags); -+ set_bit(WDM_RESPONDING, &desc->flags); - if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { - rv = usb_submit_urb(desc->response, GFP_ATOMIC); - dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", -@@ -234,6 +238,7 @@ static void wdm_int_callback(struct urb - } - spin_unlock(&desc->iuspin); - if (rv < 0) { -+ clear_bit(WDM_RESPONDING, &desc->flags); - if (rv == -EPERM) - return; - if (rv == -ENOMEM) { -@@ -795,7 +800,8 @@ static int wdm_suspend(struct usb_interf - mutex_lock(&desc->lock); - #ifdef CONFIG_PM - if ((message.event & PM_EVENT_AUTO) && -- test_bit(WDM_IN_USE, &desc->flags)) { -+ (test_bit(WDM_IN_USE, &desc->flags) -+ || test_bit(WDM_RESPONDING, &desc->flags))) { - rv = -EBUSY; - } else { - #endif diff --git a/usb.current/usb-cdc-wdm-fix-race-between-disconnect-and-debug-messages.patch b/usb.current/usb-cdc-wdm-fix-race-between-disconnect-and-debug-messages.patch deleted file mode 100644 index 106a670d91def8..00000000000000 --- a/usb.current/usb-cdc-wdm-fix-race-between-disconnect-and-debug-messages.patch +++ /dev/null @@ -1,43 +0,0 @@ -From oliver@neukum.org Mon Mar 15 16:14:21 2010 -From: Oliver Neukum <oliver@neukum.org> -Date: Sat, 27 Feb 2010 20:55:26 +0100 -Subject: usb: cdc-wdm: Fix race between disconnect and debug messages -To: Greg KH <greg@kroah.com> -Cc: Rickard Bellini <rickard.bellini@ericsson.com> -Message-ID: <201002272055.26689.oliver@neukum.org> - -From: Oliver Neukum <oliver@neukum.org> - -dev_dbg() and dev_err() cannot be used to report failures -that may have been caused by a device's removal - -Signed-off-by: Oliver Neukum <neukum@b1-systems.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/class/cdc-wdm.c | 5 ----- - 1 file changed, 5 deletions(-) - ---- a/drivers/usb/class/cdc-wdm.c -+++ b/drivers/usb/class/cdc-wdm.c -@@ -435,11 +435,8 @@ retry: - spin_lock_irq(&desc->iuspin); - - if (desc->rerr) { /* read completed, error happened */ -- int t = desc->rerr; - desc->rerr = 0; - spin_unlock_irq(&desc->iuspin); -- dev_err(&desc->intf->dev, -- "reading had resulted in %d\n", t); - rv = -EIO; - goto err; - } -@@ -477,8 +474,6 @@ retry: - - err: - mutex_unlock(&desc->lock); -- if (rv < 0 && rv != -EAGAIN) -- dev_err(&desc->intf->dev, "wdm_read: exit error\n"); - return rv; - } - diff --git a/usb.current/usb-cdc-wdm-fix-race-between-write-and-disconnect.patch b/usb.current/usb-cdc-wdm-fix-race-between-write-and-disconnect.patch deleted file mode 100644 index c8c653cdd6af0f..00000000000000 --- a/usb.current/usb-cdc-wdm-fix-race-between-write-and-disconnect.patch +++ /dev/null @@ -1,227 +0,0 @@ -From oliver@neukum.org Mon Mar 15 16:13:35 2010 -From: Oliver Neukum <oliver@neukum.org> -Date: Sat, 27 Feb 2010 20:54:24 +0100 -Subject: usb: cdc-wdm: Fix race between write and disconnect -To: Greg KH <greg@kroah.com> -Cc: Rickard Bellini <rickard.bellini@ericsson.com> -Message-ID: <201002272054.24814.oliver@neukum.org> - -From: Oliver Neukum <oliver@neukum.org> - -Unify mutexes to fix a race between write and disconnect -and shift the test for disconnection to always report it. - -Signed-off-by: Oliver Neukum <neukum@b1-systems.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/class/cdc-wdm.c | 84 +++++++++++++++++++++++--------------------- - 1 file changed, 45 insertions(+), 39 deletions(-) - ---- a/drivers/usb/class/cdc-wdm.c -+++ b/drivers/usb/class/cdc-wdm.c -@@ -87,9 +87,7 @@ struct wdm_device { - int count; - dma_addr_t shandle; - dma_addr_t ihandle; -- struct mutex wlock; -- struct mutex rlock; -- struct mutex plock; -+ struct mutex lock; - wait_queue_head_t wait; - struct work_struct rxwork; - int werr; -@@ -305,14 +303,38 @@ static ssize_t wdm_write - if (we < 0) - return -EIO; - -- r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */ -+ desc->outbuf = buf = kmalloc(count, GFP_KERNEL); -+ if (!buf) { -+ rv = -ENOMEM; -+ goto outnl; -+ } -+ -+ r = copy_from_user(buf, buffer, count); -+ if (r > 0) { -+ kfree(buf); -+ rv = -EFAULT; -+ goto outnl; -+ } -+ -+ /* concurrent writes and disconnect */ -+ r = mutex_lock_interruptible(&desc->lock); - rv = -ERESTARTSYS; -- if (r) -+ if (r) { -+ kfree(buf); - goto outnl; -+ } -+ -+ if (test_bit(WDM_DISCONNECTING, &desc->flags)) { -+ kfree(buf); -+ rv = -ENODEV; -+ goto outnp; -+ } - - r = usb_autopm_get_interface(desc->intf); -- if (r < 0) -+ if (r < 0) { -+ kfree(buf); - goto outnp; -+ } - - if (!file->f_flags && O_NONBLOCK) - r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, -@@ -320,24 +342,8 @@ static ssize_t wdm_write - else - if (test_bit(WDM_IN_USE, &desc->flags)) - r = -EAGAIN; -- if (r < 0) -- goto out; -- -- if (test_bit(WDM_DISCONNECTING, &desc->flags)) { -- rv = -ENODEV; -- goto out; -- } -- -- desc->outbuf = buf = kmalloc(count, GFP_KERNEL); -- if (!buf) { -- rv = -ENOMEM; -- goto out; -- } -- -- r = copy_from_user(buf, buffer, count); -- if (r > 0) { -+ if (r < 0) { - kfree(buf); -- rv = -EFAULT; - goto out; - } - -@@ -374,7 +380,7 @@ static ssize_t wdm_write - out: - usb_autopm_put_interface(desc->intf); - outnp: -- mutex_unlock(&desc->wlock); -+ mutex_unlock(&desc->lock); - outnl: - return rv < 0 ? rv : count; - } -@@ -387,7 +393,7 @@ static ssize_t wdm_read - struct wdm_device *desc = file->private_data; - - -- rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ -+ rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */ - if (rv < 0) - return -ERESTARTSYS; - -@@ -465,7 +471,7 @@ retry: - rv = cntr; - - err: -- mutex_unlock(&desc->rlock); -+ mutex_unlock(&desc->lock); - if (rv < 0 && rv != -EAGAIN) - dev_err(&desc->intf->dev, "wdm_read: exit error\n"); - return rv; -@@ -533,7 +539,7 @@ static int wdm_open(struct inode *inode, - } - intf->needs_remote_wakeup = 1; - -- mutex_lock(&desc->plock); -+ mutex_lock(&desc->lock); - if (!desc->count++) { - rv = usb_submit_urb(desc->validity, GFP_KERNEL); - if (rv < 0) { -@@ -544,7 +550,7 @@ static int wdm_open(struct inode *inode, - } else { - rv = 0; - } -- mutex_unlock(&desc->plock); -+ mutex_unlock(&desc->lock); - usb_autopm_put_interface(desc->intf); - out: - mutex_unlock(&wdm_mutex); -@@ -556,9 +562,9 @@ static int wdm_release(struct inode *ino - struct wdm_device *desc = file->private_data; - - mutex_lock(&wdm_mutex); -- mutex_lock(&desc->plock); -+ mutex_lock(&desc->lock); - desc->count--; -- mutex_unlock(&desc->plock); -+ mutex_unlock(&desc->lock); - - if (!desc->count) { - dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); -@@ -655,9 +661,7 @@ next_desc: - desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); - if (!desc) - goto out; -- mutex_init(&desc->wlock); -- mutex_init(&desc->rlock); -- mutex_init(&desc->plock); -+ mutex_init(&desc->lock); - spin_lock_init(&desc->iuspin); - init_waitqueue_head(&desc->wait); - desc->wMaxCommand = maxcom; -@@ -772,7 +776,9 @@ static void wdm_disconnect(struct usb_in - clear_bit(WDM_IN_USE, &desc->flags); - spin_unlock_irqrestore(&desc->iuspin, flags); - cancel_work_sync(&desc->rxwork); -+ mutex_lock(&desc->lock); - kill_urbs(desc); -+ mutex_unlock(&desc->lock); - wake_up_all(&desc->wait); - if (!desc->count) - cleanup(desc); -@@ -786,7 +792,7 @@ static int wdm_suspend(struct usb_interf - - dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); - -- mutex_lock(&desc->plock); -+ mutex_lock(&desc->lock); - #ifdef CONFIG_PM - if ((message.event & PM_EVENT_AUTO) && - test_bit(WDM_IN_USE, &desc->flags)) { -@@ -798,7 +804,7 @@ static int wdm_suspend(struct usb_interf - #ifdef CONFIG_PM - } - #endif -- mutex_unlock(&desc->plock); -+ mutex_unlock(&desc->lock); - - return rv; - } -@@ -821,9 +827,9 @@ static int wdm_resume(struct usb_interfa - int rv; - - dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); -- mutex_lock(&desc->plock); -+ mutex_lock(&desc->lock); - rv = recover_from_urb_loss(desc); -- mutex_unlock(&desc->plock); -+ mutex_unlock(&desc->lock); - return rv; - } - -@@ -831,7 +837,7 @@ static int wdm_pre_reset(struct usb_inte - { - struct wdm_device *desc = usb_get_intfdata(intf); - -- mutex_lock(&desc->plock); -+ mutex_lock(&desc->lock); - return 0; - } - -@@ -841,7 +847,7 @@ static int wdm_post_reset(struct usb_int - int rv; - - rv = recover_from_urb_loss(desc); -- mutex_unlock(&desc->plock); -+ mutex_unlock(&desc->lock); - return 0; - } - diff --git a/usb.current/usb-cdc-wdm-fix-submission-of-urb-after-suspension.patch b/usb.current/usb-cdc-wdm-fix-submission-of-urb-after-suspension.patch deleted file mode 100644 index 725bfa6b42418e..00000000000000 --- a/usb.current/usb-cdc-wdm-fix-submission-of-urb-after-suspension.patch +++ /dev/null @@ -1,58 +0,0 @@ -From oliver@neukum.org Mon Mar 15 16:14:43 2010 -From: Oliver Neukum <oliver@neukum.org> -Date: Sat, 27 Feb 2010 20:55:52 +0100 -Subject: usb: cdc-wdm: Fix submission of URB after suspension -To: Greg KH <greg@kroah.com> -Cc: Rickard Bellini <rickard.bellini@ericsson.com> -Message-ID: <201002272055.52974.oliver@neukum.org> - -From: Oliver Neukum <oliver@neukum.org> - -There's a window under which cdc-wdm may submit -an URB to a device about to be suspended. This -introduces a flag to prevent it. - -Signed-off-by: Oliver Neukum <neukum@b1-systems.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/class/cdc-wdm.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/drivers/usb/class/cdc-wdm.c -+++ b/drivers/usb/class/cdc-wdm.c -@@ -53,7 +53,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); - #define WDM_INT_STALL 5 - #define WDM_POLL_RUNNING 6 - #define WDM_RESPONDING 7 -- -+#define WDM_SUSPENDING 8 - - #define WDM_MAX 16 - -@@ -231,7 +231,8 @@ static void wdm_int_callback(struct urb - spin_lock(&desc->iuspin); - clear_bit(WDM_READ, &desc->flags); - set_bit(WDM_RESPONDING, &desc->flags); -- if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { -+ if (!test_bit(WDM_DISCONNECTING, &desc->flags) -+ && !test_bit(WDM_SUSPENDING, &desc->flags)) { - rv = usb_submit_urb(desc->response, GFP_ATOMIC); - dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", - __func__, rv); -@@ -800,6 +801,7 @@ static int wdm_suspend(struct usb_interf - rv = -EBUSY; - } else { - #endif -+ set_bit(WDM_SUSPENDING, &desc->flags); - cancel_work_sync(&desc->rxwork); - kill_urbs(desc); - #ifdef CONFIG_PM -@@ -830,6 +832,7 @@ static int wdm_resume(struct usb_interfa - dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); - mutex_lock(&desc->lock); - rv = recover_from_urb_loss(desc); -+ clear_bit(WDM_SUSPENDING, &desc->flags); - mutex_unlock(&desc->lock); - return rv; - } diff --git a/usb.current/usb-cp210x-remove-double-usb_control_msg-from-cp210x_set_config.patch b/usb.current/usb-cp210x-remove-double-usb_control_msg-from-cp210x_set_config.patch deleted file mode 100644 index b94c1d23476f66..00000000000000 --- a/usb.current/usb-cp210x-remove-double-usb_control_msg-from-cp210x_set_config.patch +++ /dev/null @@ -1,35 +0,0 @@ -From mibru@gmx.de Tue Mar 16 13:27:47 2010 -From: Michael Brunner <mibru@gmx.de> -Date: Wed, 10 Mar 2010 23:26:37 +0100 -Subject: USB: cp210x: Remove double usb_control_msg from cp210x_set_config -To: craig@microtron.org.uk, gregkh@suse.de -Message-ID: <20100310232637.7e14e773@mail.gmx.de> - - -This patch removes a double usb_control_msg that sets the cp210x -configuration registers a second time when calling cp210x_set_config. -For data sizes >2 the second write gets corrupted. -The patch has been created against 2.6.34-rc1, but all cp210x driver -revisions are affected. - -Signed-off-by: Michael Brunner <mibru@gmx.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/cp210x.c | 5 ----- - 1 file changed, 5 deletions(-) - ---- a/drivers/usb/serial/cp210x.c -+++ b/drivers/usb/serial/cp210x.c -@@ -313,11 +313,6 @@ static int cp210x_set_config(struct usb_ - return -EPROTO; - } - -- /* Single data value */ -- result = usb_control_msg(serial->dev, -- usb_sndctrlpipe(serial->dev, 0), -- request, REQTYPE_HOST_TO_DEVICE, data[0], -- 0, NULL, 0, 300); - return 0; - } - diff --git a/usb.current/usb-ehci-adjust-ehci_iso_stream-for-changes-in-ehci_qh.patch b/usb.current/usb-ehci-adjust-ehci_iso_stream-for-changes-in-ehci_qh.patch deleted file mode 100644 index afc358d0e5a043..00000000000000 --- a/usb.current/usb-ehci-adjust-ehci_iso_stream-for-changes-in-ehci_qh.patch +++ /dev/null @@ -1,68 +0,0 @@ -From clemens@ladisch.de Mon Mar 15 13:19:09 2010 -From: Clemens Ladisch <clemens@ladisch.de> -Date: Mon, 01 Mar 2010 17:18:56 +0100 -Subject: USB: EHCI: adjust ehci_iso_stream for changes in ehci_qh -To: Alan Stern <stern@rowland.harvard.edu> -Cc: linux-usb@vger.kernel.org, David Brownell <dbrownell@users.sourceforge.net>, Alek Du <alek.du@intel.com>, Colin Fletcher <colin.m.fletcher@googlemail.com> -Message-ID: <4B8BE8F0.4050508@ladisch.de> - -The EHCI driver stores in usb_host_endpoint.hcpriv a pointer to either -an ehci_qh or an ehci_iso_stream structure, and uses the contents of the -hw_info1 field to distinguish the two cases. - -After ehci_qh was split into hw and sw parts, ehci_iso_stream must also -be adjusted so that it again looks like an ehci_qh structure. - -This fixes a NULL pointer access in ehci_endpoint_disable() when it -tries to access qh->hw->hw_info1. - -Signed-off-by: Clemens Ladisch <clemens@ladisch.de> -Reported-by: Colin Fletcher <colin.m.fletcher@googlemail.com> -Cc: stable <stable@kernel.org> -Acked-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/ehci-hcd.c | 2 +- - drivers/usb/host/ehci-sched.c | 4 ++-- - drivers/usb/host/ehci.h | 5 ++--- - 3 files changed, 5 insertions(+), 6 deletions(-) - ---- a/drivers/usb/host/ehci-hcd.c -+++ b/drivers/usb/host/ehci-hcd.c -@@ -995,7 +995,7 @@ rescan: - /* endpoints can be iso streams. for now, we don't - * accelerate iso completions ... so spin a while. - */ -- if (qh->hw->hw_info1 == 0) { -+ if (qh->hw == NULL) { - ehci_vdbg (ehci, "iso delay\n"); - goto idle_timeout; - } ---- a/drivers/usb/host/ehci-sched.c -+++ b/drivers/usb/host/ehci-sched.c -@@ -1123,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci, - urb->interval); - } - -- /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */ -- } else if (unlikely (stream->hw_info1 != 0)) { -+ /* if dev->ep [epnum] is a QH, hw is set */ -+ } else if (unlikely (stream->hw != NULL)) { - ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", - urb->dev->devpath, epnum, - usb_pipein(urb->pipe) ? "in" : "out"); ---- a/drivers/usb/host/ehci.h -+++ b/drivers/usb/host/ehci.h -@@ -394,9 +394,8 @@ struct ehci_iso_sched { - * acts like a qh would, if EHCI had them for ISO. - */ - struct ehci_iso_stream { -- /* first two fields match QH, but info1 == 0 */ -- __hc32 hw_next; -- __hc32 hw_info1; -+ /* first field matches ehci_hq, but is NULL */ -+ struct ehci_qh_hw *hw; - - u32 refcount; - u8 bEndpointAddress; diff --git a/usb.current/usb-ehci-fix-itd-list-order.patch b/usb.current/usb-ehci-fix-itd-list-order.patch deleted file mode 100644 index b6928d3ba67994..00000000000000 --- a/usb.current/usb-ehci-fix-itd-list-order.patch +++ /dev/null @@ -1,62 +0,0 @@ -From clemens@ladisch.de Mon Mar 15 13:18:20 2010 -From: Clemens Ladisch <clemens@ladisch.de> -Date: Mon, 01 Mar 2010 09:12:50 +0100 -Subject: USB: EHCI: fix ITD list order -To: linux-usb@vger.kernel.org, David Brownell <dbrownell@users.sourceforge.net> -Cc: Colin Fletcher <colin.m.fletcher@googlemail.com> -Message-ID: <4B8B7702.4050107@ladisch.de> - - -When isochronous URBs are shorter than one frame and when more than one -ITD in a frame has been completed before the interrupt can be handled, -scan_periodic() completes the URBs in the order in which they are found -in the descriptor list. Therefore, the descriptor list must contain the -ITDs in the correct order, i.e., a new ITD must be linked in after any -previous ITDs of the same endpoint. - -This should fix garbled capture data in the USB audio drivers. - -Signed-off-by: Clemens Ladisch <clemens@ladisch.de> -Reported-by: Colin Fletcher <colin.m.fletcher@googlemail.com> -Cc: stable <stable@kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/ehci-sched.c | 24 +++++++++++++++++++----- - 1 file changed, 19 insertions(+), 5 deletions(-) - ---- a/drivers/usb/host/ehci-sched.c -+++ b/drivers/usb/host/ehci-sched.c -@@ -1565,13 +1565,27 @@ itd_patch( - static inline void - itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) - { -- /* always prepend ITD/SITD ... only QH tree is order-sensitive */ -- itd->itd_next = ehci->pshadow [frame]; -- itd->hw_next = ehci->periodic [frame]; -- ehci->pshadow [frame].itd = itd; -+ union ehci_shadow *prev = &ehci->pshadow[frame]; -+ __hc32 *hw_p = &ehci->periodic[frame]; -+ union ehci_shadow here = *prev; -+ __hc32 type = 0; -+ -+ /* skip any iso nodes which might belong to previous microframes */ -+ while (here.ptr) { -+ type = Q_NEXT_TYPE(ehci, *hw_p); -+ if (type == cpu_to_hc32(ehci, Q_TYPE_QH)) -+ break; -+ prev = periodic_next_shadow(ehci, prev, type); -+ hw_p = shadow_next_periodic(ehci, &here, type); -+ here = *prev; -+ } -+ -+ itd->itd_next = here; -+ itd->hw_next = *hw_p; -+ prev->itd = itd; - itd->frame = frame; - wmb (); -- ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); -+ *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); - } - - /* fit urb's itds into the selected schedule slot; activate as needed */ diff --git a/usb.current/usb-fix-documentation-for-avoid_reset_quirk.patch b/usb.current/usb-fix-documentation-for-avoid_reset_quirk.patch deleted file mode 100644 index c952bcdef5b1b9..00000000000000 --- a/usb.current/usb-fix-documentation-for-avoid_reset_quirk.patch +++ /dev/null @@ -1,31 +0,0 @@ -From oliver@neukum.org Mon Mar 15 15:21:04 2010 -From: Oliver Neukum <oliver@neukum.org> -Date: Fri, 12 Mar 2010 11:27:21 +0100 -Subject: USB: Fix documentation for avoid_reset_quirk -To: Greg KH <greg@kroah.com> -Cc: Josua Dietze <digidietze@draisberghof.de> -Message-ID: <201003121127.21352.oliver@neukum.org> - - -From: Oliver Neukum <oliver@neukum.org> - -The name used in the documentation doesn't match reality. - -Signed-off-by: Oliver Neukum <neukum@b1-systems.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/ABI/testing/sysfs-bus-usb | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/Documentation/ABI/testing/sysfs-bus-usb -+++ b/Documentation/ABI/testing/sysfs-bus-usb -@@ -160,7 +160,7 @@ Description: - match the driver to the device. For example: - # echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id - --What: /sys/bus/usb/device/.../avoid_reset -+What: /sys/bus/usb/device/.../avoid_reset_quirk - Date: December 2009 - Contact: Oliver Neukum <oliver@neukum.org> - Description: diff --git a/usb.current/usb-fix-usb_fill_int_urb-for-superspeed-devices.patch b/usb.current/usb-fix-usb_fill_int_urb-for-superspeed-devices.patch deleted file mode 100644 index b3a29a1cadf4a4..00000000000000 --- a/usb.current/usb-fix-usb_fill_int_urb-for-superspeed-devices.patch +++ /dev/null @@ -1,85 +0,0 @@ -From sarah.a.sharp@linux.intel.com Tue Mar 16 13:37:38 2010 -From: Matthew Wilcox <willy@linux.intel.com> -Date: Tue, 16 Mar 2010 12:55:44 -0700 -Subject: USB: Fix usb_fill_int_urb for SuperSpeed devices -To: Greg KH <gregkh@suse.de> -Cc: linux-usb@vger.kernel.org, Matthew Wilcox <willy@linux.intel.com> -Message-ID: <20100316195351.GA28341@xanatos> -Content-Disposition: inline - - -From: Matthew Wilcox <willy@linux.intel.com> - -USB 3 and Wireless USB specify a logarithmic encoding of the endpoint -interval that matches the USB 2 specification. usb_fill_int_urb() didn't -know that and was filling in the interval as if it was USB 1.1. Fix -usb_fill_int_urb() for SuperSpeed devices, but leave the wireless case -alone, because David Vrabel wants to keep the old encoding. - -Update the struct urb kernel doc to note that SuperSpeed URBs must have -urb->interval specified in microframes. - -Add a missing break statement in the usb_submit_urb() interrupt URB -checking, since wireless USB and SuperSpeed USB encode urb->interval -differently. This allows xHCI roothubs to actually register with khubd. - -Signed-off-by: Matthew Wilcox <willy@linux.intel.com> -Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/core/urb.c | 1 + - include/linux/usb.h | 18 +++++++++++++----- - 2 files changed, 14 insertions(+), 5 deletions(-) - ---- a/drivers/usb/core/urb.c -+++ b/drivers/usb/core/urb.c -@@ -453,6 +453,7 @@ int usb_submit_urb(struct urb *urb, gfp_ - if (urb->interval > (1 << 15)) - return -EINVAL; - max = 1 << 15; -+ break; - case USB_SPEED_WIRELESS: - if (urb->interval > 16) - return -EINVAL; ---- a/include/linux/usb.h -+++ b/include/linux/usb.h -@@ -1055,7 +1055,8 @@ typedef void (*usb_complete_t)(struct ur - * @number_of_packets: Lists the number of ISO transfer buffers. - * @interval: Specifies the polling interval for interrupt or isochronous - * transfers. The units are frames (milliseconds) for full and low -- * speed devices, and microframes (1/8 millisecond) for highspeed ones. -+ * speed devices, and microframes (1/8 millisecond) for highspeed -+ * and SuperSpeed devices. - * @error_count: Returns the number of ISO transfers that reported errors. - * @context: For use in completion functions. This normally points to - * request-specific driver context. -@@ -1286,9 +1287,16 @@ static inline void usb_fill_bulk_urb(str - * - * Initializes a interrupt urb with the proper information needed to submit - * it to a device. -- * Note that high speed interrupt endpoints use a logarithmic encoding of -- * the endpoint interval, and express polling intervals in microframes -- * (eight per millisecond) rather than in frames (one per millisecond). -+ * -+ * Note that High Speed and SuperSpeed interrupt endpoints use a logarithmic -+ * encoding of the endpoint interval, and express polling intervals in -+ * microframes (eight per millisecond) rather than in frames (one per -+ * millisecond). -+ * -+ * Wireless USB also uses the logarithmic encoding, but specifies it in units of -+ * 128us instead of 125us. For Wireless USB devices, the interval is passed -+ * through to the host controller, rather than being translated into microframe -+ * units. - */ - static inline void usb_fill_int_urb(struct urb *urb, - struct usb_device *dev, -@@ -1305,7 +1313,7 @@ static inline void usb_fill_int_urb(stru - urb->transfer_buffer_length = buffer_length; - urb->complete = complete_fn; - urb->context = context; -- if (dev->speed == USB_SPEED_HIGH) -+ if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER) - urb->interval = 1 << (interval - 1); - else - urb->interval = interval; diff --git a/usb.current/usb-fix-usbfs-regression.patch b/usb.current/usb-fix-usbfs-regression.patch deleted file mode 100644 index 10275a4b7ff7bf..00000000000000 --- a/usb.current/usb-fix-usbfs-regression.patch +++ /dev/null @@ -1,57 +0,0 @@ -From stern@rowland.harvard.edu Mon Mar 15 13:13:23 2010 -From: Alan Stern <stern@rowland.harvard.edu> -Date: Sat, 6 Mar 2010 15:04:03 -0500 (EST) -Subject: USB: fix usbfs regression -To: Greg KH <greg@kroah.com> -Cc: Markus Rechberger <mrechberger@gmail.com>, <werner@guyane.dyn-o-saur.com>, Marcus Meissner <meissner@suse.de> -Message-ID: <Pine.LNX.4.44L0.1003061459500.22767-100000@netrider.rowland.org> - - -This patch (as1352) fixes a bug in the way isochronous input data is -returned to userspace for usbfs transfers. The entire buffer must be -copied, not just the first actual_length bytes, because the individual -packets will be discontiguous if any of them are short. - -Reported-by: Markus Rechberger <mrechberger@gmail.com> -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -CC: stable <stable@kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/core/devio.c | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - ---- a/drivers/usb/core/devio.c -+++ b/drivers/usb/core/devio.c -@@ -1207,6 +1207,13 @@ static int proc_do_submiturb(struct dev_ - free_async(as); - return -ENOMEM; - } -+ /* Isochronous input data may end up being discontiguous -+ * if some of the packets are short. Clear the buffer so -+ * that the gaps don't leak kernel data to userspace. -+ */ -+ if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO) -+ memset(as->urb->transfer_buffer, 0, -+ uurb->buffer_length); - } - as->urb->dev = ps->dev; - as->urb->pipe = (uurb->type << 30) | -@@ -1345,10 +1352,14 @@ static int processcompl(struct async *as - void __user *addr = as->userurb; - unsigned int i; - -- if (as->userbuffer && urb->actual_length) -- if (copy_to_user(as->userbuffer, urb->transfer_buffer, -- urb->actual_length)) -+ if (as->userbuffer && urb->actual_length) { -+ if (urb->number_of_packets > 0) /* Isochronous */ -+ i = urb->transfer_buffer_length; -+ else /* Non-Isoc */ -+ i = urb->actual_length; -+ if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) - goto err_out; -+ } - if (put_user(as->status, &userurb->status)) - goto err_out; - if (put_user(urb->actual_length, &userurb->actual_length)) diff --git a/usb.current/usb-ftdi_sio-fix-locking-for-change_speed-function.patch b/usb.current/usb-ftdi_sio-fix-locking-for-change_speed-function.patch deleted file mode 100644 index 0a615e1e38c15d..00000000000000 --- a/usb.current/usb-ftdi_sio-fix-locking-for-change_speed-function.patch +++ /dev/null @@ -1,52 +0,0 @@ -From abogani@texware.it Mon Mar 15 16:39:50 2010 -From: Alessio Igor Bogani <abogani@texware.it> -Date: Sat, 13 Mar 2010 18:35:14 +0100 -Subject: USB: ftdi_sio: Fix locking for change_speed() function -To: Greg Kroah-Hartman <gregkh@suse.de> -Cc: Johan Hovold <jhovold@gmail.com>, Alan Cox <alan@linux.intel.com>, Daniel Mack <daniel@caiaq.de>, Mark Adamson <mark.adamson@ftdichip.com>, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Alessio Igor Bogani <abogani@texware.it> -Message-ID: <1268501714-5464-1-git-send-email-abogani@texware.it> - - -The change_speed() function should be serialized against multiple calls. -Use the cfg_lock mutex to do this. - -Signed-off-by: Alessio Igor Bogani <abogani@texware.it> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/ftdi_sio.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/usb/serial/ftdi_sio.c -+++ b/drivers/usb/serial/ftdi_sio.c -@@ -91,7 +91,7 @@ struct ftdi_private { - unsigned long tx_outstanding_bytes; - unsigned long tx_outstanding_urbs; - unsigned short max_packet_size; -- struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() */ -+ struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ - }; - - /* struct ftdi_sio_quirk is used by devices requiring special attention. */ -@@ -1273,8 +1273,8 @@ check_and_exit: - (priv->flags & ASYNC_SPD_MASK)) || - (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && - (old_priv.custom_divisor != priv->custom_divisor))) { -- mutex_unlock(&priv->cfg_lock); - change_speed(tty, port); -+ mutex_unlock(&priv->cfg_lock); - } - else - mutex_unlock(&priv->cfg_lock); -@@ -2265,9 +2265,11 @@ static void ftdi_set_termios(struct tty_ - clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); - } else { - /* set the baudrate determined before */ -+ mutex_lock(&priv->cfg_lock); - if (change_speed(tty, port)) - dev_err(&port->dev, "%s urb failed to set baudrate\n", - __func__); -+ mutex_unlock(&priv->cfg_lock); - /* Ensure RTS and DTR are raised when baudrate changed from 0 */ - if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) - set_mctrl(port, TIOCM_DTR | TIOCM_RTS); diff --git a/usb.current/usb-g_mass_storage-fix-section-mismatch-warnings.patch b/usb.current/usb-g_mass_storage-fix-section-mismatch-warnings.patch deleted file mode 100644 index f703b37ac5f949..00000000000000 --- a/usb.current/usb-g_mass_storage-fix-section-mismatch-warnings.patch +++ /dev/null @@ -1,36 +0,0 @@ -From vapier@gentoo.org Mon Mar 15 16:36:54 2010 -From: Mike Frysinger <vapier@gentoo.org> -Date: Sun, 7 Mar 2010 10:36:27 -0500 -Subject: USB: g_mass_storage: fix section mismatch warnings -To: linux-usb@vger.kernel.org, Greg Kroah-Hartman <gregkh@suse.de> -Message-ID: <1267976187-32648-1-git-send-email-vapier@gentoo.org> - - -The recent commit (0e530b45783f75) that moved usb_ep_autoconfig from the -__devinit section to the __init section missed the mass storage device. -Its fsg_bind() function uses the usb_ep_autoconfig() function from non -__init context leading to: -WARNING: drivers/usb/gadget/g_mass_storage.o(.text): Section mismatch in - reference from the function _fsg_bind() - to the function .init.text:_usb_ep_autoconfig() - -So move fsg_bind() into __init as well. - -Signed-off-by: Mike Frysinger <vapier@gentoo.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/f_mass_storage.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/gadget/f_mass_storage.c -+++ b/drivers/usb/gadget/f_mass_storage.c -@@ -2910,7 +2910,7 @@ static void fsg_unbind(struct usb_config - } - - --static int fsg_bind(struct usb_configuration *c, struct usb_function *f) -+static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f) - { - struct fsg_dev *fsg = fsg_from_func(f); - struct usb_gadget *gadget = c->cdev->gadget; diff --git a/usb.current/usb-g_mass_storage-fixed-module-name-in-kconfig.patch b/usb.current/usb-g_mass_storage-fixed-module-name-in-kconfig.patch deleted file mode 100644 index 42fdd3dc8cd2aa..00000000000000 --- a/usb.current/usb-g_mass_storage-fixed-module-name-in-kconfig.patch +++ /dev/null @@ -1,32 +0,0 @@ -From m.nazarewicz@samsung.com Mon Mar 15 16:38:24 2010 -From: Michal Nazarewicz <m.nazarewicz@samsung.com> -Date: Mon, 15 Mar 2010 11:10:23 +0100 -Subject: USB: g_mass_storage: fixed module name in Kconfig -To: linux-usb@vger.kernel.org, David Brownell <dbrownell@users.sourceforge.net> -Cc: gregkh@suse.de, linux-kernel@vger.kernel.org, Marek Szyprowski <m.szyprowski@samsung.com>, Michal Nazarewicz <m.nazarewicz@samsung.com>, Kyungmin Park <kyungmin.park@samsung.com> -Message-ID: <6c04e7ae998c9bb5ea8ecb9c2e96bfe8fb4d7da3.1268220008.git.mina86@mina86.com> - - -The Kconfig help message for Mass Storage Gadget claimed the -module will be named "g_file_storage" whereas it should be -"g_mass_storage". - -Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com> -Cc: Kyungmin Park <kyungmin.park@samsung.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/gadget/Kconfig -+++ b/drivers/usb/gadget/Kconfig -@@ -747,7 +747,7 @@ config USB_MASS_STORAGE - which may be used with composite framework. - - Say "y" to link the driver statically, or "m" to build -- a dynamically linked module called "g_file_storage". If unsure, -+ a dynamically linked module called "g_mass_storage". If unsure, - consider File-backed Storage Gadget. - - config USB_G_SERIAL diff --git a/usb.current/usb-gadget-add-gadget-controller-number-for-s3c-hsotg-driver.patch b/usb.current/usb-gadget-add-gadget-controller-number-for-s3c-hsotg-driver.patch deleted file mode 100644 index e76a65196cd48a..00000000000000 --- a/usb.current/usb-gadget-add-gadget-controller-number-for-s3c-hsotg-driver.patch +++ /dev/null @@ -1,41 +0,0 @@ -From mcuelenaere@gmail.com Mon Mar 15 16:33:42 2010 -From: Maurus Cuelenaere <mcuelenaere@gmail.com> -Date: Mon, 8 Mar 2010 18:20:59 +0100 -Subject: USB: gadget: add gadget controller number for s3c-hsotg driver -To: linux-usb@vger.kernel.org -Message-ID: <b2e8f9f71003080920q1e473a8an1d8c361082d2ff6b@mail.gmail.com> - - -This prevents some drivers from complaining that no bcdDevice id was set. - -Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/gadget_chips.h | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/usb/gadget/gadget_chips.h -+++ b/drivers/usb/gadget/gadget_chips.h -@@ -136,6 +136,12 @@ - #define gadget_is_r8a66597(g) 0 - #endif - -+#ifdef CONFIG_USB_S3C_HSOTG -+#define gadget_is_s3c_hsotg(g) (!strcmp("s3c-hsotg", (g)->name)) -+#else -+#define gadget_is_s3c_hsotg(g) 0 -+#endif -+ - - /** - * usb_gadget_controller_number - support bcdDevice id convention -@@ -192,6 +198,8 @@ static inline int usb_gadget_controller_ - return 0x24; - else if (gadget_is_r8a66597(gadget)) - return 0x25; -+ else if (gadget_is_s3c_hsotg(gadget)) -+ return 0x26; - return -ENOENT; - } - diff --git a/usb.current/usb-gadget-f_mass_storage-fsg_bind-fix-error-handling.patch b/usb.current/usb-gadget-f_mass_storage-fsg_bind-fix-error-handling.patch deleted file mode 100644 index 6fec96c47ae88d..00000000000000 --- a/usb.current/usb-gadget-f_mass_storage-fsg_bind-fix-error-handling.patch +++ /dev/null @@ -1,33 +0,0 @@ -From jacmet@sunsite.dk Mon Mar 15 16:37:46 2010 -From: Peter Korsgaard <jacmet@sunsite.dk> -Date: Fri, 12 Mar 2010 15:55:28 +0100 -Subject: USB: gadget: f_mass_storage::fsg_bind(): fix error handling -To: m.nazarewicz@samsung.com, gregkh@suse.de, linux-usb@vger.kernel.org -Cc: Peter Korsgaard <jacmet@sunsite.dk> -Message-ID: <1268405728-6547-1-git-send-email-jacmet@sunsite.dk> - - -Contrary to the comment in fsg_add, fsg_bind calls fsg_unbind on errors, -which decreases refcount and frees the fsg_dev structure, causing trouble -when fsg_add does the same. - -Fix it by simply leaving up cleanup to fsg_add(). - -Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk> -Acked-by: Michal Nazarewicz <m.nazarewicz@samsung.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/f_mass_storage.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/usb/gadget/f_mass_storage.c -+++ b/drivers/usb/gadget/f_mass_storage.c -@@ -2954,7 +2954,6 @@ static int __init fsg_bind(struct usb_co - autoconf_fail: - ERROR(fsg, "unable to autoconfigure all endpoints\n"); - rc = -ENOTSUPP; -- fsg_unbind(c, f); - return rc; - } - diff --git a/usb.current/usb-gadget-fix-blackfin-builds-after-gadget-cleansing.patch b/usb.current/usb-gadget-fix-blackfin-builds-after-gadget-cleansing.patch deleted file mode 100644 index ffdefccc2f6ad5..00000000000000 --- a/usb.current/usb-gadget-fix-blackfin-builds-after-gadget-cleansing.patch +++ /dev/null @@ -1,32 +0,0 @@ -From vapier@gentoo.org Mon Mar 15 16:35:38 2010 -From: Mike Frysinger <vapier@gentoo.org> -Date: Tue, 9 Mar 2010 00:35:22 -0500 -Subject: USB: gadget: fix Blackfin builds after gadget cleansing -To: linux-usb@vger.kernel.org, Greg Kroah-Hartman <gregkh@suse.de> -Cc: Christoph Egger <siccegge@stud.informatik.uni-erlangen.de>, linux-kernel@vger.kernel.org -Message-ID: <1268112922-21601-1-git-send-email-vapier@gentoo.org> - - -The recent change to clean out dead gadget drivers (90f7976880bbbf99) -missed the call to gadget_is_musbhsfc() behind CONFIG_BLACKFIN. This -causes Blackfin gadget builds to fail since the function no longer -exists anywhere. - -Signed-off-by: Mike Frysinger <vapier@gentoo.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/epautoconf.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/gadget/epautoconf.c -+++ b/drivers/usb/gadget/epautoconf.c -@@ -266,7 +266,7 @@ struct usb_ep * __init usb_ep_autoconfig - } - - #ifdef CONFIG_BLACKFIN -- } else if (gadget_is_musbhsfc(gadget) || gadget_is_musbhdrc(gadget)) { -+ } else if (gadget_is_musbhdrc(gadget)) { - if ((USB_ENDPOINT_XFER_BULK == type) || - (USB_ENDPOINT_XFER_ISOC == type)) { - if (USB_DIR_IN & desc->bEndpointAddress) diff --git a/usb.current/usb-gadget-fix-compile-error-on-r8a66597-udc.c.patch b/usb.current/usb-gadget-fix-compile-error-on-r8a66597-udc.c.patch deleted file mode 100644 index 49ba6793b30ada..00000000000000 --- a/usb.current/usb-gadget-fix-compile-error-on-r8a66597-udc.c.patch +++ /dev/null @@ -1,27 +0,0 @@ -From grant.likely@secretlab.ca Mon Mar 15 15:22:35 2010 -From: Grant Likely <grant.likely@secretlab.ca> -Date: Thu, 11 Mar 2010 15:06:54 -0700 -Subject: usb/gadget: fix compile error on r8a66597-udc.c -To: gregkh@suse.de, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org -Message-ID: <20100311220631.19163.98586.stgit@angua> - - -C file uses IS_ERR and PTR_ERR, but doesn't include <linux/err.h> - -Signed-off-by: Grant Likely <grant.likely@secretlab.ca> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/r8a66597-udc.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/usb/gadget/r8a66597-udc.c -+++ b/drivers/usb/gadget/r8a66597-udc.c -@@ -23,6 +23,7 @@ - #include <linux/module.h> - #include <linux/interrupt.h> - #include <linux/delay.h> -+#include <linux/err.h> - #include <linux/io.h> - #include <linux/platform_device.h> - #include <linux/clk.h> diff --git a/usb.current/usb-gadget-multi-cdc_do_config-remove-redundant-check.patch b/usb.current/usb-gadget-multi-cdc_do_config-remove-redundant-check.patch deleted file mode 100644 index 08531419dee7db..00000000000000 --- a/usb.current/usb-gadget-multi-cdc_do_config-remove-redundant-check.patch +++ /dev/null @@ -1,29 +0,0 @@ -From jacmet@sunsite.dk Tue Mar 16 13:35:06 2010 -From: Peter Korsgaard <jacmet@sunsite.dk> -Date: Fri, 12 Mar 2010 12:33:15 +0100 -Subject: USB: gadget/multi: cdc_do_config: remove redundant check -To: m.nazarewicz@samsung.com, gregkh@suse.de, linux-usb@vger.kernel.org -Cc: Peter Korsgaard <jacmet@sunsite.dk> -Message-ID: <1268393595-19744-1-git-send-email-jacmet@sunsite.dk> - - -cdc_do_config() had a double ret check after fsg_add(). - -Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/multi.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/usb/gadget/multi.c -+++ b/drivers/usb/gadget/multi.c -@@ -211,8 +211,6 @@ static int __init cdc_do_config(struct u - ret = fsg_add(c->cdev, c, fsg_common); - if (ret < 0) - return ret; -- if (ret < 0) -- return ret; - - return 0; - } diff --git a/usb.current/usb-goku_udc-remove-potential-null-dereference.patch b/usb.current/usb-goku_udc-remove-potential-null-dereference.patch deleted file mode 100644 index 75a7b43e498003..00000000000000 --- a/usb.current/usb-goku_udc-remove-potential-null-dereference.patch +++ /dev/null @@ -1,32 +0,0 @@ -From error27@gmail.com Mon Mar 15 16:32:29 2010 -From: Dan Carpenter <error27@gmail.com> -Date: Sat, 6 Mar 2010 14:08:56 +0300 -Subject: USB: goku_udc: remove potential null dereference -To: David Brownell <dbrownell@users.sourceforge.net> -Cc: Greg Kroah-Hartman <gregkh@suse.de>, Matthias Kaehlcke <matthias@kaehlcke.net>, Harvey Harrison <harvey.harrison@gmail.com>, N�meth M�rton <nm127@freemail.hu> -Message-ID: <20100306110856.GF4958@bicker> -Content-Disposition: inline - - -"dev" is always null here. In the end it's only used to get the -pci_name() of "pdev" which is redundant information and so I -removed it. - -Signed-off-by: Dan Carpenter <error27@gmail.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/goku_udc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/gadget/goku_udc.c -+++ b/drivers/usb/gadget/goku_udc.c -@@ -1768,7 +1768,7 @@ static int goku_probe(struct pci_dev *pd - * usb_gadget_driver_{register,unregister}() must change. - */ - if (the_controller) { -- WARNING(dev, "ignoring %s\n", pci_name(pdev)); -+ pr_warning("ignoring %s\n", pci_name(pdev)); - return -EBUSY; - } - if (!pdev->irq) { diff --git a/usb.current/usb-musb-abstract-out-ulpi_buscontrol-register-reads-writes.patch b/usb.current/usb-musb-abstract-out-ulpi_buscontrol-register-reads-writes.patch deleted file mode 100644 index 2dc688949356fa..00000000000000 --- a/usb.current/usb-musb-abstract-out-ulpi_buscontrol-register-reads-writes.patch +++ /dev/null @@ -1,99 +0,0 @@ -From felipe.balbi@nokia.com Mon Mar 15 15:28:10 2010 -From: Felipe Balbi <felipe.balbi@nokia.com> -Date: Fri, 12 Mar 2010 10:27:21 +0200 -Subject: usb: musb: abstract out ULPI_BUSCONTROL register reads/writes -To: Greg KH <greg@kroah.com> -Cc: Mike Frysinger <vapier@gentoo.org>, Felipe Balbi <felipe.balbi@nokia.com> -Message-ID: <1268382444-7340-3-git-send-email-felipe.balbi@nokia.com> - - -From: Mike Frysinger <vapier@gentoo.org> - -The USB PHY on current Blackfin processors is a UTMI+ level 2 PHY. -However, it has no ULPI support - so there are no registers at all. -That means accesses to ULPI_BUSCONTROL have to be abstracted away -like other MUSB registers. - -This fixes building for Blackfin parts again. - -Signed-off-by: Mike Frysinger <vapier@gentoo.org> -Acked-by: Anand Gadiyar <gadiyar@ti.com> -Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/musb/musb_core.c | 5 ++--- - drivers/usb/musb/musb_regs.h | 19 +++++++++++++++++++ - 2 files changed, 21 insertions(+), 3 deletions(-) - ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -2007,7 +2007,6 @@ bad_config: - /* host side needs more setup */ - if (is_host_enabled(musb)) { - struct usb_hcd *hcd = musb_to_hcd(musb); -- u8 busctl; - - otg_set_host(musb->xceiv, &hcd->self); - -@@ -2018,9 +2017,9 @@ bad_config: - - /* program PHY to use external vBus if required */ - if (plat->extvbus) { -- busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL); -+ u8 busctl = musb_read_ulpi_buscontrol(musb->mregs); - busctl |= MUSB_ULPI_USE_EXTVBUS; -- musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl); -+ musb_write_ulpi_buscontrol(musb->mregs, busctl); - } - } - ---- a/drivers/usb/musb/musb_regs.h -+++ b/drivers/usb/musb/musb_regs.h -@@ -326,6 +326,11 @@ static inline void musb_write_rxfifoadd - musb_writew(mbase, MUSB_RXFIFOADD, c_off); - } - -+static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) -+{ -+ musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val); -+} -+ - static inline u8 musb_read_txfifosz(void __iomem *mbase) - { - return musb_readb(mbase, MUSB_TXFIFOSZ); -@@ -346,6 +351,11 @@ static inline u16 musb_read_rxfifoadd(v - return musb_readw(mbase, MUSB_RXFIFOADD); - } - -+static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) -+{ -+ return musb_readb(mbase, MUSB_ULPI_BUSCONTROL); -+} -+ - static inline u8 musb_read_configdata(void __iomem *mbase) - { - musb_writeb(mbase, MUSB_INDEX, 0); -@@ -510,6 +520,10 @@ static inline void musb_write_rxfifoadd - { - } - -+static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) -+{ -+} -+ - static inline u8 musb_read_txfifosz(void __iomem *mbase) - { - } -@@ -526,6 +540,11 @@ static inline u16 musb_read_rxfifoadd(v - { - } - -+static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) -+{ -+ return 0; -+} -+ - static inline u8 musb_read_configdata(void __iomem *mbase) - { - return 0; diff --git a/usb.current/usb-musb-core-declare-mbase-only-where-it-s-used.patch b/usb.current/usb-musb-core-declare-mbase-only-where-it-s-used.patch deleted file mode 100644 index 5c88ff6cb5f3c6..00000000000000 --- a/usb.current/usb-musb-core-declare-mbase-only-where-it-s-used.patch +++ /dev/null @@ -1,64 +0,0 @@ -From felipe.balbi@nokia.com Mon Mar 15 15:29:06 2010 -From: Felipe Balbi <felipe.balbi@nokia.com> -Date: Fri, 12 Mar 2010 10:27:24 +0200 -Subject: usb: musb: core: declare mbase only where it's used -To: Greg KH <greg@kroah.com> -Cc: Felipe Balbi <felipe.balbi@nokia.com> -Message-ID: <1268382444-7340-6-git-send-email-felipe.balbi@nokia.com> - - -... and avoid a compilation if we disable host side -of musb. - -Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/musb/musb_core.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -379,7 +379,6 @@ static irqreturn_t musb_stage0_irq(struc - u8 devctl, u8 power) - { - irqreturn_t handled = IRQ_NONE; -- void __iomem *mbase = musb->mregs; - - DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, - int_usb); -@@ -394,6 +393,8 @@ static irqreturn_t musb_stage0_irq(struc - - if (devctl & MUSB_DEVCTL_HM) { - #ifdef CONFIG_USB_MUSB_HDRC_HCD -+ void __iomem *mbase = musb->mregs; -+ - switch (musb->xceiv->state) { - case OTG_STATE_A_SUSPEND: - /* remote wakeup? later, GetPortStatus -@@ -471,6 +472,8 @@ static irqreturn_t musb_stage0_irq(struc - #ifdef CONFIG_USB_MUSB_HDRC_HCD - /* see manual for the order of the tests */ - if (int_usb & MUSB_INTR_SESSREQ) { -+ void __iomem *mbase = musb->mregs; -+ - DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); - - /* IRQ arrives from ID pin sense or (later, if VBUS power -@@ -519,6 +522,8 @@ static irqreturn_t musb_stage0_irq(struc - case OTG_STATE_A_WAIT_BCON: - case OTG_STATE_A_WAIT_VRISE: - if (musb->vbuserr_retry) { -+ void __iomem *mbase = musb->mregs; -+ - musb->vbuserr_retry--; - ignore = 1; - devctl |= MUSB_DEVCTL_SESSION; -@@ -622,6 +627,7 @@ static irqreturn_t musb_stage0_irq(struc - - if (int_usb & MUSB_INTR_CONNECT) { - struct usb_hcd *hcd = musb_to_hcd(musb); -+ void __iomem *mbase = musb->mregs; - - handled = IRQ_HANDLED; - musb->is_active = 1; diff --git a/usb.current/usb-musb-fix-build-error-introduced-by-isoc-change.patch b/usb.current/usb-musb-fix-build-error-introduced-by-isoc-change.patch deleted file mode 100644 index 5f9ffec10c2083..00000000000000 --- a/usb.current/usb-musb-fix-build-error-introduced-by-isoc-change.patch +++ /dev/null @@ -1,37 +0,0 @@ -From vapier@gentoo.org Mon Mar 15 15:09:13 2010 -From: Sonic Zhang <sonic.zhang@analog.com> -Date: Mon, 8 Mar 2010 11:26:01 -0500 -Subject: USB: musb: fix build error introduced by isoc change -To: linux-usb@vger.kernel.org, Felipe Balbi <felipe.balbi@nokia.com> -Cc: stable@kernel.org, stable-review@kernel.org, linux-kernel@vger.kernel.org, Sonic Zhang <sonic.zhang@analog.com> -Message-ID: <1268065561-24350-1-git-send-email-vapier@gentoo.org> - - -From: Sonic Zhang <sonic.zhang@analog.com> - -The recent commit "usb: musb: Fix for isochronous IN transfer" (f82a689fa) -seems to have been against an older kernel version. It uses the old style -naming of variables. Unfortunately, this breaks building for most MUSB -users out there since "bDesiredMode" has been renamed to "desired_mode". - -Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> -Signed-off-by: Mike Frysinger <vapier@gentoo.org> -Acked-by: Felipe Balbi <felipe.balbi@nokia.com> -Acked-by: Anand Gadiyar <gadiyar@ti.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/musb/musb_host.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -1689,7 +1689,7 @@ void musb_host_rx(struct musb *musb, u8 - dma->desired_mode = 1; - if (rx_count < hw_ep->max_packet_sz_rx) { - length = rx_count; -- dma->bDesiredMode = 0; -+ dma->desired_mode = 0; - } else { - length = urb->transfer_buffer_length; - } diff --git a/usb.current/usb-musb-fix-compile-error-for-omaps-for-musb_hdrc.patch b/usb.current/usb-musb-fix-compile-error-for-omaps-for-musb_hdrc.patch deleted file mode 100644 index d473bcfea0bb3c..00000000000000 --- a/usb.current/usb-musb-fix-compile-error-for-omaps-for-musb_hdrc.patch +++ /dev/null @@ -1,51 +0,0 @@ -From felipe.balbi@nokia.com Mon Mar 15 15:26:51 2010 -From: Felipe Balbi <felipe.balbi@nokia.com> -Date: Fri, 12 Mar 2010 10:35:20 +0200 -Subject: usb: musb: Fix compile error for omaps for musb_hdrc -To: Greg KH <greg@kroah.com> -Cc: Tony Lindgren <tony@atomide.com>, Felipe Balbi <felipe.balbi@nokia.com> -Message-ID: <1268382920-10786-1-git-send-email-felipe.balbi@nokia.com> - - -From: Tony Lindgren <tony@atomide.com> - -CONFIG_ARCH_OMAP34XX is now CONFIG_ARCH_OMAP3. - -But since drivers/usb/musb/omap2430.c use CONFIG_PM for these -registers and functions, do the same for the header. - -Otherwise we get the following for most omap3 defconfigs: - -drivers/usb/musb/omap2430.c:261: error: expected identifier or '(' before 'do' -drivers/usb/musb/omap2430.c:261: error: expected identifier or '(' before 'while' -drivers/usb/musb/omap2430.c:268: error: expected identifier or '(' before 'do' -drivers/usb/musb/omap2430.c:268: error: expected identifier or '(' before 'while' - -Signed-off-by: Tony Lindgren <tony@atomide.com> -Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/musb/musb_core.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/usb/musb/musb_core.h -+++ b/drivers/usb/musb/musb_core.h -@@ -469,7 +469,7 @@ struct musb_csr_regs { - - struct musb_context_registers { - --#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) -+#ifdef CONFIG_PM - u32 otg_sysconfig, otg_forcestandby; - #endif - u8 power; -@@ -483,7 +483,7 @@ struct musb_context_registers { - struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; - }; - --#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) -+#ifdef CONFIG_PM - extern void musb_platform_save_context(struct musb *musb, - struct musb_context_registers *musb_context); - extern void musb_platform_restore_context(struct musb *musb, diff --git a/usb.current/usb-musb-fix-warnings-in-blackfin-regs.patch b/usb.current/usb-musb-fix-warnings-in-blackfin-regs.patch deleted file mode 100644 index 2f82a94c04a298..00000000000000 --- a/usb.current/usb-musb-fix-warnings-in-blackfin-regs.patch +++ /dev/null @@ -1,75 +0,0 @@ -From felipe.balbi@nokia.com Mon Mar 15 15:28:47 2010 -From: Mike Frysinger <vapier@gentoo.org> -Date: Fri, 12 Mar 2010 10:27:23 +0200 -Subject: USB: musb: fix warnings in Blackfin regs -To: Greg KH <greg@kroah.com> -Cc: Mike Frysinger <vapier@gentoo.org>, Felipe Balbi <felipe.balbi@nokia.com> -Message-ID: <1268382444-7340-5-git-send-email-felipe.balbi@nokia.com> - -From: Mike Frysinger <vapier@gentoo.org> - -The recent commit "usb: musb: Add context save and restore support" added -some stubs for the Blackfin code so things would compile, but it also -added a bunch of warnings due to missing return statements. - -Signed-off-by: Mike Frysinger <vapier@gentoo.org> -Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/musb/musb_regs.h | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/drivers/usb/musb/musb_regs.h -+++ b/drivers/usb/musb/musb_regs.h -@@ -526,18 +526,22 @@ static inline void musb_write_ulpi_busco - - static inline u8 musb_read_txfifosz(void __iomem *mbase) - { -+ return 0; - } - - static inline u16 musb_read_txfifoadd(void __iomem *mbase) - { -+ return 0; - } - - static inline u8 musb_read_rxfifosz(void __iomem *mbase) - { -+ return 0; - } - - static inline u16 musb_read_rxfifoadd(void __iomem *mbase) - { -+ return 0; - } - - static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) -@@ -596,22 +600,27 @@ static inline void musb_write_txhubport - - static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) - { -+ return 0; - } - - static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) - { -+ return 0; - } - - static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) - { -+ return 0; - } - - static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) - { -+ return 0; - } - - static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) - { -+ return 0; - } - - static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) diff --git a/usb.current/usb-option-add-support-for-a-new-cmotech-device-to-usb-serial-option.patch b/usb.current/usb-option-add-support-for-a-new-cmotech-device-to-usb-serial-option.patch deleted file mode 100644 index 858ad9f2d23fe5..00000000000000 --- a/usb.current/usb-option-add-support-for-a-new-cmotech-device-to-usb-serial-option.patch +++ /dev/null @@ -1,34 +0,0 @@ -From nathaniel@natemccallum.com Mon Mar 15 15:20:26 2010 -From: Nathaniel McCallum <nathaniel@natemccallum.com> -Date: Thu, 11 Mar 2010 13:09:26 -0500 -Subject: USB: option: add support for a new CMOTECH device to usb/serial/option -Cc: gregkh@suse.de, smurf@smurf.noris.de, gernot@hillier.de, r0bertz@gentoo.org, stern@rowland.harvard.edu, Nathaniel McCallum <nathaniel@natemccallum.com> -Message-ID: <1268330966-6862-3-git-send-email-nathaniel@natemccallum.com> - - -Signed-off-by: Nathaniel McCallum <nathaniel@natemccallum.com> -Cc: stable <stable@kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/option.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -289,6 +289,7 @@ static int option_resume(struct usb_ser - #define QUALCOMM_VENDOR_ID 0x05C6 - - #define CMOTECH_VENDOR_ID 0x16d8 -+#define CMOTECH_PRODUCT_6008 0x6008 - #define CMOTECH_PRODUCT_6280 0x6280 - - #define TELIT_VENDOR_ID 0x1bc7 -@@ -550,6 +551,7 @@ static const struct usb_device_id option - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ - { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ -+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ diff --git a/usb.current/usb-option-add-support-for-a-variant-of-dlink-dwm-652-u5.patch b/usb.current/usb-option-add-support-for-a-variant-of-dlink-dwm-652-u5.patch deleted file mode 100644 index 70e2cf5f45d038..00000000000000 --- a/usb.current/usb-option-add-support-for-a-variant-of-dlink-dwm-652-u5.patch +++ /dev/null @@ -1,47 +0,0 @@ -From huang.ying.caritas@gmail.com Mon Mar 15 13:17:47 2010 -From: Huang Ying <huang.ying.caritas@gmail.com> -Date: Sun, 28 Feb 2010 13:51:29 +0800 -Subject: USB: Option: Add support for a variant of DLink DWM 652 U5 -To: Greg KH <gregkh@suse.de> -Message-ID: <1267336289.9610.2.camel@caritas-mobile.ml.org> - - -I found a DLink DWM 652 U5 USB 3G modem has product ID 0xce1e instead -of orignal 0xce16. The new ID is added. - -And I found there are two entries for 0xce16, one has raw number, the -other has symbol DLINK_PRODUCT_DWM_652_U5. This is fixed too. - -Signed-off-by: Huang Ying <ying.huang@intel.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/option.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -309,6 +309,7 @@ static int option_resume(struct usb_ser - #define DLINK_VENDOR_ID 0x1186 - #define DLINK_PRODUCT_DWM_652 0x3e04 - #define DLINK_PRODUCT_DWM_652_U5 0xce16 -+#define DLINK_PRODUCT_DWM_652_U5A 0xce1e - - #define QISDA_VENDOR_ID 0x1da5 - #define QISDA_PRODUCT_H21_4512 0x4512 -@@ -659,6 +660,7 @@ static const struct usb_device_id option - { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, - { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, - { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ -+ { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5A) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, -@@ -666,7 +668,6 @@ static const struct usb_device_id option - { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, - { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ - { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, -- { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) }, - { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, - { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, - { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, diff --git a/usb.current/usb-option-fix-incorrect-manufacturer-name-in-usb-serial-option-maxon-cmotech.patch b/usb.current/usb-option-fix-incorrect-manufacturer-name-in-usb-serial-option-maxon-cmotech.patch deleted file mode 100644 index 24587519ea647f..00000000000000 --- a/usb.current/usb-option-fix-incorrect-manufacturer-name-in-usb-serial-option-maxon-cmotech.patch +++ /dev/null @@ -1,36 +0,0 @@ -From nathaniel@natemccallum.com Mon Mar 15 15:19:36 2010 -From: Nathaniel McCallum <nathaniel@natemccallum.com> -Date: Thu, 11 Mar 2010 13:09:24 -0500 -Subject: USB: option: fix incorrect manufacturer name in usb/serial/option: MAXON->CMOTECH -Cc: linux-kernel@vger.kernel.org, gregkh@suse.de, smurf@smurf.noris.de, gernot@hillier.de, r0bertz@gentoo.org, stern@rowland.harvard.edu, Nathaniel McCallum <nathaniel@natemccallum.com> -Message-ID: <1268330966-6862-1-git-send-email-nathaniel@natemccallum.com> - - -Signed-off-by: Nathaniel McCallum <nathaniel@natemccallum.com> -Cc: stable <stable@kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/option.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -288,7 +288,7 @@ static int option_resume(struct usb_ser - - #define QUALCOMM_VENDOR_ID 0x05C6 - --#define MAXON_VENDOR_ID 0x16d8 -+#define CMOTECH_VENDOR_ID 0x16d8 - - #define TELIT_VENDOR_ID 0x1bc7 - #define TELIT_PRODUCT_UC864E 0x1003 -@@ -548,7 +548,7 @@ static const struct usb_device_id option - { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ -- { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ -+ { USB_DEVICE(CMOTECH_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ diff --git a/usb.current/usb-option-move-hardcoded-pid-to-a-macro-in-usb-serial-option.patch b/usb.current/usb-option-move-hardcoded-pid-to-a-macro-in-usb-serial-option.patch deleted file mode 100644 index 883f3eac4acda3..00000000000000 --- a/usb.current/usb-option-move-hardcoded-pid-to-a-macro-in-usb-serial-option.patch +++ /dev/null @@ -1,35 +0,0 @@ -From nathaniel@natemccallum.com Mon Mar 15 15:20:03 2010 -From: Nathaniel McCallum <nathaniel@natemccallum.com> -Date: Thu, 11 Mar 2010 13:01:17 -0500 -Subject: USB: option: move hardcoded PID to a macro in usb/serial/option -Cc: gregkh@suse.de, smurf@smurf.noris.de, gernot@hillier.de, r0bertz@gentoo.org, stern@rowland.harvard.edu, Nathaniel McCallum <nathaniel@natemccallum.com> -Message-ID: <1268330478-6689-2-git-send-email-nathaniel@natemccallum.com> - - -Signed-off-by: Nathaniel McCallum <nathaniel@natemccallum.com> -Cc: stable <stable@kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/option.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -289,6 +289,7 @@ static int option_resume(struct usb_ser - #define QUALCOMM_VENDOR_ID 0x05C6 - - #define CMOTECH_VENDOR_ID 0x16d8 -+#define CMOTECH_PRODUCT_6280 0x6280 - - #define TELIT_VENDOR_ID 0x1bc7 - #define TELIT_PRODUCT_UC864E 0x1003 -@@ -548,7 +549,7 @@ static const struct usb_device_id option - { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ -- { USB_DEVICE(CMOTECH_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ -+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ diff --git a/usb.current/usb-option.c-add-pirelli-vid-pid-and-indicate-pirelli-s-modem-interface-is-0xff.patch b/usb.current/usb-option.c-add-pirelli-vid-pid-and-indicate-pirelli-s-modem-interface-is-0xff.patch deleted file mode 100644 index 38dcea0aee6b2d..00000000000000 --- a/usb.current/usb-option.c-add-pirelli-vid-pid-and-indicate-pirelli-s-modem-interface-is-0xff.patch +++ /dev/null @@ -1,86 +0,0 @@ -From spark@bandrich.com Mon Mar 15 16:22:53 2010 -From: "spark" <spark@bandrich.com> -Date: Fri, 5 Mar 2010 14:18:05 +0800 -Subject: USB: option.c: Add Pirelli VID/PID and indicate Pirelli's modem interface is 0xff -To: "'Greg KH'" <gregkh@suse.de> -Message-ID: <F0D81B598E4A41B387B41E41E0E1B297@brtpe.com> - -Signed-off-by: spark <spark@bandrich.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/option.c | 43 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 43 insertions(+) - ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -335,6 +335,24 @@ static int option_resume(struct usb_ser - #define ALCATEL_VENDOR_ID 0x1bbb - #define ALCATEL_PRODUCT_X060S 0x0000 - -+#define PIRELLI_VENDOR_ID 0x1266 -+#define PIRELLI_PRODUCT_C100_1 0x1002 -+#define PIRELLI_PRODUCT_C100_2 0x1003 -+#define PIRELLI_PRODUCT_1004 0x1004 -+#define PIRELLI_PRODUCT_1005 0x1005 -+#define PIRELLI_PRODUCT_1006 0x1006 -+#define PIRELLI_PRODUCT_1007 0x1007 -+#define PIRELLI_PRODUCT_1008 0x1008 -+#define PIRELLI_PRODUCT_1009 0x1009 -+#define PIRELLI_PRODUCT_100A 0x100a -+#define PIRELLI_PRODUCT_100B 0x100b -+#define PIRELLI_PRODUCT_100C 0x100c -+#define PIRELLI_PRODUCT_100D 0x100d -+#define PIRELLI_PRODUCT_100E 0x100e -+#define PIRELLI_PRODUCT_100F 0x100f -+#define PIRELLI_PRODUCT_1011 0x1011 -+#define PIRELLI_PRODUCT_1012 0x1012 -+ - /* Airplus products */ - #define AIRPLUS_VENDOR_ID 0x1011 - #define AIRPLUS_PRODUCT_MCD650 0x3198 -@@ -679,6 +697,24 @@ static const struct usb_device_id option - .driver_info = (kernel_ulong_t)&four_g_w14_blacklist - }, - { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, -+ /* Pirelli */ -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)}, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)}, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)}, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)}, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)}, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)}, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)}, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)}, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) }, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) }, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) }, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) }, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, -+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, -+ - { } /* Terminating entry */ - }; - MODULE_DEVICE_TABLE(usb, option_ids); -@@ -802,12 +838,19 @@ static int option_probe(struct usb_seria - const struct usb_device_id *id) - { - struct option_intf_private *data; -+ - /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ - if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && - serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && - serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) - return -ENODEV; - -+ /* Bandrich modem and AT command interface is 0xff */ -+ if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID || -+ serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) && -+ serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) -+ return -ENODEV; -+ - data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); - if (!data) - return -ENOMEM; diff --git a/usb.current/usb-qcserial-add-new-device-ids.patch b/usb.current/usb-qcserial-add-new-device-ids.patch deleted file mode 100644 index 39e3a39a0f23f5..00000000000000 --- a/usb.current/usb-qcserial-add-new-device-ids.patch +++ /dev/null @@ -1,56 +0,0 @@ -From br@blankpage.ch Mon Mar 15 15:07:59 2010 -From: Bernhard Rosenkraenzer <br@blankpage.ch> -Date: Wed, 10 Mar 2010 12:36:43 +0100 -Subject: USB: qcserial: add new device ids -To: Greg KH <gregkh@suse.de> -Message-ID: <1ad0620b49866cf33763372aca56efdb@blankpage.ch> - -This patch adds various USB device IDs for Gobi 2000 devices, as found in the -drivers available at https://www.codeaurora.org/wiki/GOBI_Releases - -Signed-off-by: Bernhard Rosenkraenzer <bero@arklinux.org> -Cc: stable <stable@kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/qcserial.c | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - ---- a/drivers/usb/serial/qcserial.c -+++ b/drivers/usb/serial/qcserial.c -@@ -47,6 +47,35 @@ static const struct usb_device_id id_tab - {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ - {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ - {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ -+ {USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */ -+ {USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ -+ {USB_DEVICE(0x05c6, 0x9224)}, /* Sony Gobi 2000 QDL device (N0279, VU730) */ -+ {USB_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ -+ {USB_DEVICE(0x05c6, 0x9244)}, /* Samsung Gobi 2000 QDL device (VL176) */ -+ {USB_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ -+ {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */ -+ {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ -+ {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */ -+ {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ -+ {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */ -+ {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ -+ {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */ -+ {USB_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ -+ {USB_DEVICE(0x05c6, 0x9274)}, /* iRex Technologies Gobi 2000 QDL device (VR307) */ -+ {USB_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ -+ {USB_DEVICE(0x1199, 0x9000)}, /* Sierra Wireless Gobi 2000 QDL device (VT773) */ -+ {USB_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ -+ {USB_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ -+ {USB_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ -+ {USB_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ -+ {USB_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ -+ {USB_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ -+ {USB_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ -+ {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ -+ {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ -+ {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ -+ {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ -+ {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ - { } /* Terminating entry */ - }; - MODULE_DEVICE_TABLE(usb, id_table); diff --git a/usb.current/usb-r8a66597-hcd-fix-removed-from-an-attached-hub.patch b/usb.current/usb-r8a66597-hcd-fix-removed-from-an-attached-hub.patch deleted file mode 100644 index e871a573b60d5b..00000000000000 --- a/usb.current/usb-r8a66597-hcd-fix-removed-from-an-attached-hub.patch +++ /dev/null @@ -1,74 +0,0 @@ -From shimoda.yoshihiro@renesas.com Tue Mar 16 13:38:39 2010 -From: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> -Date: Tue, 16 Mar 2010 12:29:35 +0900 -Subject: usb: r8a66597-hcd: fix removed from an attached hub -To: Paul Mundt <lethal@linux-sh.org>, "Pietrek, Markus" <Markus.Pietrek@emtrion.de> -Cc: Alan Stern <stern@rowland.harvard.edu>, linux-sh@vger.kernel.org, USB list <linux-usb@vger.kernel.org> -Message-ID: <4B9EFB1F.3090201@renesas.com> - - -fix the problem that when a USB hub is attached to the r8a66597-hcd and -a device is removed from that hub, it's likely that a kernel panic follows. - -Reported-by: Markus Pietrek <Markus.Pietrek@emtrion.de> -Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> -Cc: stable <stable@kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/r8a66597-hcd.c | 16 +++++++++++----- - 1 file changed, 11 insertions(+), 5 deletions(-) - ---- a/drivers/usb/host/r8a66597-hcd.c -+++ b/drivers/usb/host/r8a66597-hcd.c -@@ -418,7 +418,7 @@ static u8 alloc_usb_address(struct r8a66 - - /* this function must be called with interrupt disabled */ - static void free_usb_address(struct r8a66597 *r8a66597, -- struct r8a66597_device *dev) -+ struct r8a66597_device *dev, int reset) - { - int port; - -@@ -430,7 +430,13 @@ static void free_usb_address(struct r8a6 - dev->state = USB_STATE_DEFAULT; - r8a66597->address_map &= ~(1 << dev->address); - dev->address = 0; -- dev_set_drvdata(&dev->udev->dev, NULL); -+ /* -+ * Only when resetting USB, it is necessary to erase drvdata. When -+ * a usb device with usb hub is disconnect, "dev->udev" is already -+ * freed on usb_desconnect(). So we cannot access the data. -+ */ -+ if (reset) -+ dev_set_drvdata(&dev->udev->dev, NULL); - list_del(&dev->device_list); - kfree(dev); - -@@ -1069,7 +1075,7 @@ static void r8a66597_usb_disconnect(stru - struct r8a66597_device *dev = r8a66597->root_hub[port].dev; - - disable_r8a66597_pipe_all(r8a66597, dev); -- free_usb_address(r8a66597, dev); -+ free_usb_address(r8a66597, dev, 0); - - start_root_hub_sampling(r8a66597, port, 0); - } -@@ -2085,7 +2091,7 @@ static void update_usb_address_map(struc - spin_lock_irqsave(&r8a66597->lock, flags); - dev = get_r8a66597_device(r8a66597, addr); - disable_r8a66597_pipe_all(r8a66597, dev); -- free_usb_address(r8a66597, dev); -+ free_usb_address(r8a66597, dev, 0); - put_child_connect_map(r8a66597, addr); - spin_unlock_irqrestore(&r8a66597->lock, flags); - } -@@ -2228,7 +2234,7 @@ static int r8a66597_hub_control(struct u - rh->port |= (1 << USB_PORT_FEAT_RESET); - - disable_r8a66597_pipe_all(r8a66597, dev); -- free_usb_address(r8a66597, dev); -+ free_usb_address(r8a66597, dev, 1); - - r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, - get_dvstctr_reg(port)); diff --git a/usb.current/usb-remove-last-bit-of-config_usb_berry_charge.patch b/usb.current/usb-remove-last-bit-of-config_usb_berry_charge.patch deleted file mode 100644 index 064b994d7fcec5..00000000000000 --- a/usb.current/usb-remove-last-bit-of-config_usb_berry_charge.patch +++ /dev/null @@ -1,46 +0,0 @@ -From siccegge@stud.informatik.uni-erlangen.de Tue Mar 16 12:01:19 2010 -From: Christoph Egger <siccegge@stud.informatik.uni-erlangen.de> -Date: Wed, 10 Mar 2010 12:33:11 +0100 -Subject: USB: Remove last bit of CONFIG_USB_BERRY_CHARGE -To: Jeremy Katz <katzj@redhat.com>, Matthew Dharm <mdharm-usb@one-eyed-alien.net>, Greg Kroah-Hartman <gregkh@suse.de>, Alan Stern <stern@rowland.harvard.edu>, Phil Dibowitz <phil@ipom.com>, Jan Dumon <j.dumon@option.com> -Cc: vamos@i4.informatik.uni-erlangen.de -Message-ID: <20100310113311.GA2824@faui49.informatik.uni-erlangen.de> -Content-Disposition: inline - - -From: Christoph Egger <siccegge@stud.informatik.uni-erlangen.de> - -One last bit was missed while removing the USB_BERRY_CHARGE config -option in a8d4211f33a9573f7b1bdcfd9c9c48631d1515ee which gets dropped -by this patch. - -Signed-off-by: Christoph Egger <siccegge@stud.informatik.uni-erlangen.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/storage/unusual_devs.h | 14 -------------- - 1 file changed, 14 deletions(-) - ---- a/drivers/usb/storage/unusual_devs.h -+++ b/drivers/usb/storage/unusual_devs.h -@@ -1389,20 +1389,6 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE ), - --/* Jeremy Katz <katzj@redhat.com>: -- * The Blackberry Pearl can run in two modes; a usb-storage only mode -- * and a mode that allows access via mass storage and to its database. -- * The berry_charge module will set the device to dual mode and thus we -- * should ignore its native mode if that module is built -- */ --#ifdef CONFIG_USB_BERRY_CHARGE --UNUSUAL_DEV( 0x0fca, 0x0006, 0x0001, 0x0001, -- "RIM", -- "Blackberry Pearl", -- US_SC_DEVICE, US_PR_DEVICE, NULL, -- US_FL_IGNORE_DEVICE ), --#endif -- - /* Reported by Michael Stattmann <michael@stattmann.com> */ - UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, - "Sony Ericsson", diff --git a/usb.current/usb-serial-fix-error-message-on-close-in-generic-driver.patch b/usb.current/usb-serial-fix-error-message-on-close-in-generic-driver.patch deleted file mode 100644 index a70c4105e9d4b3..00000000000000 --- a/usb.current/usb-serial-fix-error-message-on-close-in-generic-driver.patch +++ /dev/null @@ -1,36 +0,0 @@ -From jhovold@gmail.com Mon Mar 15 13:14:47 2010 -From: Johan Hovold <jhovold@gmail.com> -Date: Sat, 27 Feb 2010 14:05:46 +0100 -Subject: USB: serial: fix error message on close in generic driver -To: Greg Kroah-Hartman <gregkh@suse.de> -Cc: linux-usb@vger.kernel.org, Johan Hovold <jhovold@gmail.com> -Message-ID: <1267275946-31463-1-git-send-email-jhovold@gmail.com> - - -Resubmitting read urb fails with -EPERM if completion handler runs while -urb is being killed on close. This should not be reported as an error. - -Signed-off-by: Johan Hovold <jhovold@gmail.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/generic.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/usb/serial/generic.c -+++ b/drivers/usb/serial/generic.c -@@ -415,11 +415,13 @@ void usb_serial_generic_resubmit_read_ur - ((serial->type->read_bulk_callback) ? - serial->type->read_bulk_callback : - usb_serial_generic_read_bulk_callback), port); -+ - result = usb_submit_urb(urb, mem_flags); -- if (result) -+ if (result && result != -EPERM) { - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, result); -+ } - } - EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); - diff --git a/usb.current/usb-serial-fix-module-name-typo-for-qcaux-kconfig-entry.patch b/usb.current/usb-serial-fix-module-name-typo-for-qcaux-kconfig-entry.patch deleted file mode 100644 index 26250eb761c774..00000000000000 --- a/usb.current/usb-serial-fix-module-name-typo-for-qcaux-kconfig-entry.patch +++ /dev/null @@ -1,38 +0,0 @@ -From stefan@datenfreihafen.org Mon Mar 15 16:18:52 2010 -From: Stefan Schmidt <stefan@datenfreihafen.org> -Date: Wed, 3 Mar 2010 19:37:12 +0100 -Subject: USB: serial: Fix module name typo for qcaux Kconfig entry. -To: Greg Kroah-Hartman <gregkh@suse.de> -Cc: Stefan Schmidt <stefan@datenfreihafen.org> -Message-ID: <1267641432-17774-1-git-send-email-stefan@datenfreihafen.org> - - -The module is called qcaux and not moto_modem. Also use help instead of ----help-- to be in sync with the other Kconfig entries. - -Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/Kconfig | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/usb/serial/Kconfig -+++ b/drivers/usb/serial/Kconfig -@@ -474,14 +474,14 @@ config USB_SERIAL_OTI6858 - - config USB_SERIAL_QCAUX - tristate "USB Qualcomm Auxiliary Serial Port Driver" -- ---help--- -+ help - Say Y here if you want to use the auxiliary serial ports provided - by many modems based on Qualcomm chipsets. These ports often use - a proprietary protocol called DM and cannot be used for AT- or - PPP-based communication. - - To compile this driver as a module, choose M here: the -- module will be called moto_modem. If unsure, choose N. -+ module will be called qcaux. If unsure, choose N. - - config USB_SERIAL_QUALCOMM - tristate "USB Qualcomm Serial modem" diff --git a/usb.current/usb-serial-fix-softint-not-being-called-on-errors.patch b/usb.current/usb-serial-fix-softint-not-being-called-on-errors.patch deleted file mode 100644 index fef41950a1bb0b..00000000000000 --- a/usb.current/usb-serial-fix-softint-not-being-called-on-errors.patch +++ /dev/null @@ -1,50 +0,0 @@ -From jhovold@gmail.com Mon Mar 15 13:15:18 2010 -From: Johan Hovold <jhovold@gmail.com> -Date: Sat, 27 Feb 2010 14:06:07 +0100 -Subject: USB: serial: fix softint not being called on errors -To: Greg Kroah-Hartman <gregkh@suse.de> -Cc: linux-usb@vger.kernel.org, Johan Hovold <jhovold@gmail.com> -Message-ID: <1267275967-31534-1-git-send-email-jhovold@gmail.com> - - -Make sure usb_serial_port_softint is called on errors also when using -multi urb writes. - -Signed-off-by: Johan Hovold <jhovold@gmail.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/generic.c | 15 +++++---------- - 1 file changed, 5 insertions(+), 10 deletions(-) - ---- a/drivers/usb/serial/generic.c -+++ b/drivers/usb/serial/generic.c -@@ -500,23 +500,18 @@ void usb_serial_generic_write_bulk_callb - if (port->urbs_in_flight < 0) - port->urbs_in_flight = 0; - spin_unlock_irqrestore(&port->lock, flags); -- -- if (status) { -- dbg("%s - nonzero multi-urb write bulk status " -- "received: %d", __func__, status); -- return; -- } - } else { - port->write_urb_busy = 0; - -- if (status) { -- dbg("%s - nonzero multi-urb write bulk status " -- "received: %d", __func__, status); -+ if (status) - kfifo_reset_out(&port->write_fifo); -- } else -+ else - usb_serial_generic_write_start(port); - } - -+ if (status) -+ dbg("%s - non-zero urb status: %d", __func__, status); -+ - usb_serial_port_softint(port); - } - EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); diff --git a/usb.current/usb-serial-ftdi-add-contec-vendor-and-product-id.patch b/usb.current/usb-serial-ftdi-add-contec-vendor-and-product-id.patch deleted file mode 100644 index 71102966dcff5c..00000000000000 --- a/usb.current/usb-serial-ftdi-add-contec-vendor-and-product-id.patch +++ /dev/null @@ -1,53 +0,0 @@ -From akpm@linux-foundation.org Mon Mar 15 15:14:50 2010 -From: Daniel Sangorrin <daniel.sangorrin@gmail.com> -Date: Thu, 11 Mar 2010 14:10:58 -0800 -Subject: USB: serial: ftdi: add CONTEC vendor and product id -To: greg@kroah.com -Cc: linux-usb@vger.kernel.org, akpm@linux-foundation.org, daniel.sangorrin@gmail.com, andi@lisas.de, gregkh@suse.de, liboska@uochb.cas.cz -Message-ID: <201003112210.o2BMAw1a013719@imap1.linux-foundation.org> - - -From: Daniel Sangorrin <daniel.sangorrin@gmail.com> - -This is a patch to ftdi_sio_ids.h and ftdi_sio.c that adds identifiers for -CONTEC USB serial converter. I tested it with the device COM-1(USB)H - -[akpm@linux-foundation.org: keep the VIDs sorted a bit] -Signed-off-by: Daniel Sangorrin <daniel.sangorrin@gmail.com> -Cc: Andreas Mohr <andi@lisas.de> -Cc: Radek Liboska <liboska@uochb.cas.cz> -Cc: stable <stable@kernel.org> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/ftdi_sio.c | 1 + - drivers/usb/serial/ftdi_sio_ids.h | 7 +++++++ - 2 files changed, 8 insertions(+) - ---- a/drivers/usb/serial/ftdi_sio.c -+++ b/drivers/usb/serial/ftdi_sio.c -@@ -658,6 +658,7 @@ static struct usb_device_id id_table_com - { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, - { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, - { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, -+ { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, ---- a/drivers/usb/serial/ftdi_sio_ids.h -+++ b/drivers/usb/serial/ftdi_sio_ids.h -@@ -501,6 +501,13 @@ - #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ - - /* -+ * Contec products (http://www.contec.com) -+ * Submitted by Daniel Sangorrin -+ */ -+#define CONTEC_VID 0x06CE /* Vendor ID */ -+#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ -+ -+/* - * Definitions for B&B Electronics products. - */ - #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ diff --git a/usb.current/usb-serial-use-port-endpoint-size-to-determine-if-ep-is-available.patch b/usb.current/usb-serial-use-port-endpoint-size-to-determine-if-ep-is-available.patch deleted file mode 100644 index e0b991573bb3a0..00000000000000 --- a/usb.current/usb-serial-use-port-endpoint-size-to-determine-if-ep-is-available.patch +++ /dev/null @@ -1,115 +0,0 @@ -From jhovold@gmail.com Mon Mar 15 13:15:47 2010 -From: Johan Hovold <jhovold@gmail.com> -Date: Sat, 27 Feb 2010 16:24:49 +0100 -Subject: USB: serial: use port endpoint size to determine if ep is available -To: Greg Kroah-Hartman <gregkh@suse.de> -Cc: linux-usb@vger.kernel.org, Johan Hovold <jhovold@gmail.com> -Message-ID: <1267284289-21866-1-git-send-email-jhovold@gmail.com> - - -It is possible to have a multi-port device with a port lacking an in or -out bulk endpoint. Only checking for num_bulk_in or num_bulk_out is thus not -sufficient to determine whether a specific port has an in or out bulk -endpoint. - -This fixes potential null pointer dereferences in the generic open and -write routines, as well as access to uninitialised fifo in write_room -and chars_in_buffer. - -Also let write fail with ENODEV (instead of 0) on missing out endpoint -(also on zero-length writes). - -Signed-off-by: Johan Hovold <jhovold@gmail.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/generic.c | 30 +++++++++++++++++++----------- - 1 file changed, 19 insertions(+), 11 deletions(-) - ---- a/drivers/usb/serial/generic.c -+++ b/drivers/usb/serial/generic.c -@@ -130,7 +130,7 @@ int usb_serial_generic_open(struct tty_s - spin_unlock_irqrestore(&port->lock, flags); - - /* if we have a bulk endpoint, start reading from it */ -- if (serial->num_bulk_in) { -+ if (port->bulk_in_size) { - /* Start reading from the device */ - usb_fill_bulk_urb(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, -@@ -159,10 +159,10 @@ static void generic_cleanup(struct usb_s - dbg("%s - port %d", __func__, port->number); - - if (serial->dev) { -- /* shutdown any bulk reads that might be going on */ -- if (serial->num_bulk_out) -+ /* shutdown any bulk transfers that might be going on */ -+ if (port->bulk_out_size) - usb_kill_urb(port->write_urb); -- if (serial->num_bulk_in) -+ if (port->bulk_in_size) - usb_kill_urb(port->read_urb); - } - } -@@ -333,15 +333,15 @@ int usb_serial_generic_write(struct tty_ - - dbg("%s - port %d", __func__, port->number); - -+ /* only do something if we have a bulk out endpoint */ -+ if (!port->bulk_out_size) -+ return -ENODEV; -+ - if (count == 0) { - dbg("%s - write request of 0 bytes", __func__); - return 0; - } - -- /* only do something if we have a bulk out endpoint */ -- if (!serial->num_bulk_out) -- return 0; -- - if (serial->type->max_in_flight_urbs) - return usb_serial_multi_urb_write(tty, port, - buf, count); -@@ -364,14 +364,19 @@ int usb_serial_generic_write_room(struct - int room = 0; - - dbg("%s - port %d", __func__, port->number); -+ -+ if (!port->bulk_out_size) -+ return 0; -+ - spin_lock_irqsave(&port->lock, flags); - if (serial->type->max_in_flight_urbs) { - if (port->urbs_in_flight < serial->type->max_in_flight_urbs) - room = port->bulk_out_size * - (serial->type->max_in_flight_urbs - - port->urbs_in_flight); -- } else if (serial->num_bulk_out) -+ } else { - room = kfifo_avail(&port->write_fifo); -+ } - spin_unlock_irqrestore(&port->lock, flags); - - dbg("%s - returns %d", __func__, room); -@@ -382,15 +387,18 @@ int usb_serial_generic_chars_in_buffer(s - { - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; -- int chars = 0; - unsigned long flags; -+ int chars; - - dbg("%s - port %d", __func__, port->number); - -+ if (!port->bulk_out_size) -+ return 0; -+ - spin_lock_irqsave(&port->lock, flags); - if (serial->type->max_in_flight_urbs) - chars = port->tx_bytes_flight; -- else if (serial->num_bulk_out) -+ else - chars = kfifo_len(&port->write_fifo); - spin_unlock_irqrestore(&port->lock, flags); - diff --git a/usb.current/usb-unusual_devs.h-fix-capacity-for-sl11r-ide-2.6c.patch b/usb.current/usb-unusual_devs.h-fix-capacity-for-sl11r-ide-2.6c.patch deleted file mode 100644 index 9578f96afd8e29..00000000000000 --- a/usb.current/usb-unusual_devs.h-fix-capacity-for-sl11r-ide-2.6c.patch +++ /dev/null @@ -1,47 +0,0 @@ -From linux@rainbow-software.org Mon Mar 15 13:17:08 2010 -From: Ondrej Zary <linux@rainbow-software.org> -Date: Sat, 27 Feb 2010 22:56:28 +0100 -Subject: USB: unusual_devs.h: Fix capacity for SL11R-IDE 2.6c -To: Phil Dibowitz <phil@ipom.com> -Cc: stern@rowland.harvard.edu, linux-usb@vger.kernel.org, usb-storage@lists.one-eyed-alien.net -Message-ID: <201002272256.31961.linux@rainbow-software.org> -Content-Disposition: inline - - -SL11R-IDE 2.6c (at least) reports wrong capacity (one sector more). -Reading that last sector causes the device not to work anymore (and looks -like HAL or something does that automatically after plugging in): -sd 5:0:0:0: [sdc] Device not ready -sd 5:0:0:0: [sdc] Result: hostbyte=0x00 driverbyte=0x08 -sd 5:0:0:0: [sdc] Sense Key : 0x2 [current] -sd 5:0:0:0: [sdc] ASC=0x0 ASCQ=0x0 -sd 5:0:0:0: [sdc] CDB: cdb[0]=0x28: 28 00 04 a8 b5 70 00 00 01 00 - -Add unusual_devs entry to fix the capacity. - -Signed-off-by: Ondrej Zary <linux@rainbow-software.org> -Signed-off-by: Phil Dibowitz <phil@ipom.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/storage/unusual_devs.h | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/drivers/usb/storage/unusual_devs.h -+++ b/drivers/usb/storage/unusual_devs.h -@@ -374,6 +374,15 @@ UNUSUAL_DEV( 0x04ce, 0x0002, 0x0074, 0x - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_INQUIRY), - -+/* Reported by Ondrej Zary <linux@rainbow-software.org> -+ * The device reports one sector more and breaks when that sector is accessed -+ */ -+UNUSUAL_DEV( 0x04ce, 0x0002, 0x026c, 0x026c, -+ "ScanLogic", -+ "SL11R-IDE", -+ US_SC_DEVICE, US_PR_DEVICE, NULL, -+ US_FL_FIX_CAPACITY), -+ - /* Reported by Kriston Fincher <kriston@airmail.net> - * Patch submitted by Sean Millichamp <sean@bruenor.org> - * This is to support the Panasonic PalmCam PV-SD4090 diff --git a/usb.current/usb-xhci-make-endpoint-interval-debugging-clearer.patch b/usb.current/usb-xhci-make-endpoint-interval-debugging-clearer.patch deleted file mode 100644 index 312bdf8f28c273..00000000000000 --- a/usb.current/usb-xhci-make-endpoint-interval-debugging-clearer.patch +++ /dev/null @@ -1,40 +0,0 @@ -From sarah.a.sharp@linux.intel.com Tue Mar 16 13:38:12 2010 -From: Sarah Sharp <sarah.a.sharp@linux.intel.com> -Date: Tue, 16 Mar 2010 12:59:24 -0700 -Subject: USB: xhci: Make endpoint interval debugging clearer. -To: Greg KH <gregkh@suse.de> -Cc: linux-usb@vger.kernel.org, Matthew Wilcox <willy@linux.intel.com> -Message-ID: <20100316195924.GA28421@xanatos> -Content-Disposition: inline - - -The xHCI hardware can only handle polling intervals that are a power of -two. When we add a new endpoint during a bandwidth allocation, and the -polling interval is rounded down to a power of two, print the original -polling interval in the endpoint descriptor. - -Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/xhci-mem.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - ---- a/drivers/usb/host/xhci-mem.c -+++ b/drivers/usb/host/xhci-mem.c -@@ -566,8 +566,13 @@ static inline unsigned int xhci_get_endp - if (interval < 3) - interval = 3; - if ((1 << interval) != 8*ep->desc.bInterval) -- dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n", -- ep->desc.bEndpointAddress, 1 << interval); -+ dev_warn(&udev->dev, -+ "ep %#x - rounding interval" -+ " to %d microframes, " -+ "ep desc says %d microframes\n", -+ ep->desc.bEndpointAddress, -+ 1 << interval, -+ 8*ep->desc.bInterval); - } - break; - default: diff --git a/usb.current/usb-xhci-re-initialize-cmd_completion.patch b/usb.current/usb-xhci-re-initialize-cmd_completion.patch deleted file mode 100644 index 17976db84a7e32..00000000000000 --- a/usb.current/usb-xhci-re-initialize-cmd_completion.patch +++ /dev/null @@ -1,34 +0,0 @@ -From andiry.xu@amd.com Mon Mar 15 15:13:38 2010 -From: Andiry Xu <andiry.xu@amd.com> -Date: Fri, 12 Mar 2010 17:10:04 +0800 -Subject: USB: xHCI: re-initialize cmd_completion -To: Sarah Sharp <sarah.a.sharp@linux.intel.com> -Cc: Greg KH <gregkh@suse.de>, linux-usb@vger.kernel.org, "Yang, Libin" <Libin.Yang@amd.com> -Message-ID: <1268385004.2633.4.camel@brienza-desktop> - -From: Andiry Xu <andiry.xu@amd.com> - -When a signal interrupts a Configure Endpoint command, the cmd_completion used -in xhci_configure_endpoint() is not re-initialized and the -wait_for_completion_interruptible_timeout() will return failure. Initialize -cmd_completion in xhci_configure_endpoint(). - -Signed-off-by: Andiry Xu <andiry.xu@amd.com> -Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> -Cc: stable <stable@kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/xhci.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/usb/host/xhci.c -+++ b/drivers/usb/host/xhci.c -@@ -1173,6 +1173,7 @@ static int xhci_configure_endpoint(struc - cmd_completion = &virt_dev->cmd_completion; - cmd_status = &virt_dev->cmd_status; - } -+ init_completion(cmd_completion); - - if (!ctx_change) - ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, diff --git a/usb.current/usb-xhci-rename-driver-to-xhci_hcd.patch b/usb.current/usb-xhci-rename-driver-to-xhci_hcd.patch deleted file mode 100644 index 80b69de468e9f9..00000000000000 --- a/usb.current/usb-xhci-rename-driver-to-xhci_hcd.patch +++ /dev/null @@ -1,3878 +0,0 @@ -From achiang@hp.com Tue Mar 16 13:57:49 2010 -From: Alex Chiang <achiang@hp.com> -Date: Tue, 16 Mar 2010 14:48:45 -0600 -Subject: USB: xhci: rename driver to xhci_hcd -To: greg@kroah.com -Cc: sarah.a.sharp@linux.intel.com -Message-ID: <20100316204845.GJ8278@ldl.fc.hp.com> - -Naming consistency with other USB HCDs. - -Signed-off-by: Alex Chiang <achiang@hp.com> -Cc: Sarah Sharp <sarah.a.sharp@linux.intel.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/Makefile | 4 - drivers/usb/host/xhci-hcd.c | 1916 -------------------------------------------- - drivers/usb/host/xhci.c | 1916 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 1918 insertions(+), 1918 deletions(-) - ---- a/drivers/usb/host/Makefile -+++ b/drivers/usb/host/Makefile -@@ -12,7 +12,7 @@ fhci-objs := fhci-hcd.o fhci-hub.o fhci- - ifeq ($(CONFIG_FHCI_DEBUG),y) - fhci-objs += fhci-dbg.o - endif --xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o -+xhci-hcd-objs := xhci.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o - - obj-$(CONFIG_USB_WHCI_HCD) += whci/ - -@@ -25,7 +25,7 @@ obj-$(CONFIG_USB_ISP1362_HCD) += isp1362 - obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o - obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o - obj-$(CONFIG_USB_FHCI_HCD) += fhci.o --obj-$(CONFIG_USB_XHCI_HCD) += xhci.o -+obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o - obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o - obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o - obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o ---- a/drivers/usb/host/xhci-hcd.c -+++ /dev/null -@@ -1,1916 +0,0 @@ --/* -- * xHCI host controller driver -- * -- * Copyright (C) 2008 Intel Corp. -- * -- * Author: Sarah Sharp -- * Some code borrowed from the Linux EHCI driver. -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This program is distributed in the hope that it will be useful, but -- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software Foundation, -- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#include <linux/irq.h> --#include <linux/module.h> --#include <linux/moduleparam.h> -- --#include "xhci.h" -- --#define DRIVER_AUTHOR "Sarah Sharp" --#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" -- --/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */ --static int link_quirk; --module_param(link_quirk, int, S_IRUGO | S_IWUSR); --MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); -- --/* TODO: copied from ehci-hcd.c - can this be refactored? */ --/* -- * handshake - spin reading hc until handshake completes or fails -- * @ptr: address of hc register to be read -- * @mask: bits to look at in result of read -- * @done: value of those bits when handshake succeeds -- * @usec: timeout in microseconds -- * -- * Returns negative errno, or zero on success -- * -- * Success happens when the "mask" bits have the specified value (hardware -- * handshake done). There are two failure modes: "usec" have passed (major -- * hardware flakeout), or the register reads as all-ones (hardware removed). -- */ --static int handshake(struct xhci_hcd *xhci, void __iomem *ptr, -- u32 mask, u32 done, int usec) --{ -- u32 result; -- -- do { -- result = xhci_readl(xhci, ptr); -- if (result == ~(u32)0) /* card removed */ -- return -ENODEV; -- result &= mask; -- if (result == done) -- return 0; -- udelay(1); -- usec--; -- } while (usec > 0); -- return -ETIMEDOUT; --} -- --/* -- * Disable interrupts and begin the xHCI halting process. -- */ --void xhci_quiesce(struct xhci_hcd *xhci) --{ -- u32 halted; -- u32 cmd; -- u32 mask; -- -- mask = ~(XHCI_IRQS); -- halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT; -- if (!halted) -- mask &= ~CMD_RUN; -- -- cmd = xhci_readl(xhci, &xhci->op_regs->command); -- cmd &= mask; -- xhci_writel(xhci, cmd, &xhci->op_regs->command); --} -- --/* -- * Force HC into halt state. -- * -- * Disable any IRQs and clear the run/stop bit. -- * HC will complete any current and actively pipelined transactions, and -- * should halt within 16 microframes of the run/stop bit being cleared. -- * Read HC Halted bit in the status register to see when the HC is finished. -- * XXX: shouldn't we set HC_STATE_HALT here somewhere? -- */ --int xhci_halt(struct xhci_hcd *xhci) --{ -- xhci_dbg(xhci, "// Halt the HC\n"); -- xhci_quiesce(xhci); -- -- return handshake(xhci, &xhci->op_regs->status, -- STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); --} -- --/* -- * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. -- * -- * This resets pipelines, timers, counters, state machines, etc. -- * Transactions will be terminated immediately, and operational registers -- * will be set to their defaults. -- */ --int xhci_reset(struct xhci_hcd *xhci) --{ -- u32 command; -- u32 state; -- -- state = xhci_readl(xhci, &xhci->op_regs->status); -- if ((state & STS_HALT) == 0) { -- xhci_warn(xhci, "Host controller not halted, aborting reset.\n"); -- return 0; -- } -- -- xhci_dbg(xhci, "// Reset the HC\n"); -- command = xhci_readl(xhci, &xhci->op_regs->command); -- command |= CMD_RESET; -- xhci_writel(xhci, command, &xhci->op_regs->command); -- /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ -- xhci_to_hcd(xhci)->state = HC_STATE_HALT; -- -- return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); --} -- -- --#if 0 --/* Set up MSI-X table for entry 0 (may claim other entries later) */ --static int xhci_setup_msix(struct xhci_hcd *xhci) --{ -- int ret; -- struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); -- -- xhci->msix_count = 0; -- /* XXX: did I do this right? ixgbe does kcalloc for more than one */ -- xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL); -- if (!xhci->msix_entries) { -- xhci_err(xhci, "Failed to allocate MSI-X entries\n"); -- return -ENOMEM; -- } -- xhci->msix_entries[0].entry = 0; -- -- ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count); -- if (ret) { -- xhci_err(xhci, "Failed to enable MSI-X\n"); -- goto free_entries; -- } -- -- /* -- * Pass the xhci pointer value as the request_irq "cookie". -- * If more irqs are added, this will need to be unique for each one. -- */ -- ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0, -- "xHCI", xhci_to_hcd(xhci)); -- if (ret) { -- xhci_err(xhci, "Failed to allocate MSI-X interrupt\n"); -- goto disable_msix; -- } -- xhci_dbg(xhci, "Finished setting up MSI-X\n"); -- return 0; -- --disable_msix: -- pci_disable_msix(pdev); --free_entries: -- kfree(xhci->msix_entries); -- xhci->msix_entries = NULL; -- return ret; --} -- --/* XXX: code duplication; can xhci_setup_msix call this? */ --/* Free any IRQs and disable MSI-X */ --static void xhci_cleanup_msix(struct xhci_hcd *xhci) --{ -- struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); -- if (!xhci->msix_entries) -- return; -- -- free_irq(xhci->msix_entries[0].vector, xhci); -- pci_disable_msix(pdev); -- kfree(xhci->msix_entries); -- xhci->msix_entries = NULL; -- xhci_dbg(xhci, "Finished cleaning up MSI-X\n"); --} --#endif -- --/* -- * Initialize memory for HCD and xHC (one-time init). -- * -- * Program the PAGESIZE register, initialize the device context array, create -- * device contexts (?), set up a command ring segment (or two?), create event -- * ring (one for now). -- */ --int xhci_init(struct usb_hcd *hcd) --{ -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- int retval = 0; -- -- xhci_dbg(xhci, "xhci_init\n"); -- spin_lock_init(&xhci->lock); -- if (link_quirk) { -- xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); -- xhci->quirks |= XHCI_LINK_TRB_QUIRK; -- } else { -- xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n"); -- } -- retval = xhci_mem_init(xhci, GFP_KERNEL); -- xhci_dbg(xhci, "Finished xhci_init\n"); -- -- return retval; --} -- --/* -- * Called in interrupt context when there might be work -- * queued on the event ring -- * -- * xhci->lock must be held by caller. -- */ --static void xhci_work(struct xhci_hcd *xhci) --{ -- u32 temp; -- u64 temp_64; -- -- /* -- * Clear the op reg interrupt status first, -- * so we can receive interrupts from other MSI-X interrupters. -- * Write 1 to clear the interrupt status. -- */ -- temp = xhci_readl(xhci, &xhci->op_regs->status); -- temp |= STS_EINT; -- xhci_writel(xhci, temp, &xhci->op_regs->status); -- /* FIXME when MSI-X is supported and there are multiple vectors */ -- /* Clear the MSI-X event interrupt status */ -- -- /* Acknowledge the interrupt */ -- temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); -- temp |= 0x3; -- xhci_writel(xhci, temp, &xhci->ir_set->irq_pending); -- /* Flush posted writes */ -- xhci_readl(xhci, &xhci->ir_set->irq_pending); -- -- if (xhci->xhc_state & XHCI_STATE_DYING) -- xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " -- "Shouldn't IRQs be disabled?\n"); -- else -- /* FIXME this should be a delayed service routine -- * that clears the EHB. -- */ -- xhci_handle_event(xhci); -- -- /* Clear the event handler busy flag (RW1C); the event ring should be empty. */ -- temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); -- xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); -- /* Flush posted writes -- FIXME is this necessary? */ -- xhci_readl(xhci, &xhci->ir_set->irq_pending); --} -- --/*-------------------------------------------------------------------------*/ -- --/* -- * xHCI spec says we can get an interrupt, and if the HC has an error condition, -- * we might get bad data out of the event ring. Section 4.10.2.7 has a list of -- * indicators of an event TRB error, but we check the status *first* to be safe. -- */ --irqreturn_t xhci_irq(struct usb_hcd *hcd) --{ -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- u32 temp, temp2; -- union xhci_trb *trb; -- -- spin_lock(&xhci->lock); -- trb = xhci->event_ring->dequeue; -- /* Check if the xHC generated the interrupt, or the irq is shared */ -- temp = xhci_readl(xhci, &xhci->op_regs->status); -- temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); -- if (temp == 0xffffffff && temp2 == 0xffffffff) -- goto hw_died; -- -- if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { -- spin_unlock(&xhci->lock); -- return IRQ_NONE; -- } -- xhci_dbg(xhci, "op reg status = %08x\n", temp); -- xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2); -- xhci_dbg(xhci, "Event ring dequeue ptr:\n"); -- xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", -- (unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb), -- lower_32_bits(trb->link.segment_ptr), -- upper_32_bits(trb->link.segment_ptr), -- (unsigned int) trb->link.intr_target, -- (unsigned int) trb->link.control); -- -- if (temp & STS_FATAL) { -- xhci_warn(xhci, "WARNING: Host System Error\n"); -- xhci_halt(xhci); --hw_died: -- xhci_to_hcd(xhci)->state = HC_STATE_HALT; -- spin_unlock(&xhci->lock); -- return -ESHUTDOWN; -- } -- -- xhci_work(xhci); -- spin_unlock(&xhci->lock); -- -- return IRQ_HANDLED; --} -- --#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING --void xhci_event_ring_work(unsigned long arg) --{ -- unsigned long flags; -- int temp; -- u64 temp_64; -- struct xhci_hcd *xhci = (struct xhci_hcd *) arg; -- int i, j; -- -- xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies); -- -- spin_lock_irqsave(&xhci->lock, flags); -- temp = xhci_readl(xhci, &xhci->op_regs->status); -- xhci_dbg(xhci, "op reg status = 0x%x\n", temp); -- if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { -- xhci_dbg(xhci, "HW died, polling stopped.\n"); -- spin_unlock_irqrestore(&xhci->lock, flags); -- return; -- } -- -- temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); -- xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); -- xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled); -- xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask); -- xhci->error_bitmask = 0; -- xhci_dbg(xhci, "Event ring:\n"); -- xhci_debug_segment(xhci, xhci->event_ring->deq_seg); -- xhci_dbg_ring_ptrs(xhci, xhci->event_ring); -- temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); -- temp_64 &= ~ERST_PTR_MASK; -- xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); -- xhci_dbg(xhci, "Command ring:\n"); -- xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg); -- xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); -- xhci_dbg_cmd_ptrs(xhci); -- for (i = 0; i < MAX_HC_SLOTS; ++i) { -- if (!xhci->devs[i]) -- continue; -- for (j = 0; j < 31; ++j) { -- struct xhci_ring *ring = xhci->devs[i]->eps[j].ring; -- if (!ring) -- continue; -- xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j); -- xhci_debug_segment(xhci, ring->deq_seg); -- } -- } -- -- if (xhci->noops_submitted != NUM_TEST_NOOPS) -- if (xhci_setup_one_noop(xhci)) -- xhci_ring_cmd_db(xhci); -- spin_unlock_irqrestore(&xhci->lock, flags); -- -- if (!xhci->zombie) -- mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ); -- else -- xhci_dbg(xhci, "Quit polling the event ring.\n"); --} --#endif -- --/* -- * Start the HC after it was halted. -- * -- * This function is called by the USB core when the HC driver is added. -- * Its opposite is xhci_stop(). -- * -- * xhci_init() must be called once before this function can be called. -- * Reset the HC, enable device slot contexts, program DCBAAP, and -- * set command ring pointer and event ring pointer. -- * -- * Setup MSI-X vectors and enable interrupts. -- */ --int xhci_run(struct usb_hcd *hcd) --{ -- u32 temp; -- u64 temp_64; -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- void (*doorbell)(struct xhci_hcd *) = NULL; -- -- hcd->uses_new_polling = 1; -- hcd->poll_rh = 0; -- -- xhci_dbg(xhci, "xhci_run\n"); --#if 0 /* FIXME: MSI not setup yet */ -- /* Do this at the very last minute */ -- ret = xhci_setup_msix(xhci); -- if (!ret) -- return ret; -- -- return -ENOSYS; --#endif --#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING -- init_timer(&xhci->event_ring_timer); -- xhci->event_ring_timer.data = (unsigned long) xhci; -- xhci->event_ring_timer.function = xhci_event_ring_work; -- /* Poll the event ring */ -- xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ; -- xhci->zombie = 0; -- xhci_dbg(xhci, "Setting event ring polling timer\n"); -- add_timer(&xhci->event_ring_timer); --#endif -- -- xhci_dbg(xhci, "Command ring memory map follows:\n"); -- xhci_debug_ring(xhci, xhci->cmd_ring); -- xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); -- xhci_dbg_cmd_ptrs(xhci); -- -- xhci_dbg(xhci, "ERST memory map follows:\n"); -- xhci_dbg_erst(xhci, &xhci->erst); -- xhci_dbg(xhci, "Event ring:\n"); -- xhci_debug_ring(xhci, xhci->event_ring); -- xhci_dbg_ring_ptrs(xhci, xhci->event_ring); -- temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); -- temp_64 &= ~ERST_PTR_MASK; -- xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); -- -- xhci_dbg(xhci, "// Set the interrupt modulation register\n"); -- temp = xhci_readl(xhci, &xhci->ir_set->irq_control); -- temp &= ~ER_IRQ_INTERVAL_MASK; -- temp |= (u32) 160; -- xhci_writel(xhci, temp, &xhci->ir_set->irq_control); -- -- /* Set the HCD state before we enable the irqs */ -- hcd->state = HC_STATE_RUNNING; -- temp = xhci_readl(xhci, &xhci->op_regs->command); -- temp |= (CMD_EIE); -- xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n", -- temp); -- xhci_writel(xhci, temp, &xhci->op_regs->command); -- -- temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); -- xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n", -- xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); -- xhci_writel(xhci, ER_IRQ_ENABLE(temp), -- &xhci->ir_set->irq_pending); -- xhci_print_ir_set(xhci, xhci->ir_set, 0); -- -- if (NUM_TEST_NOOPS > 0) -- doorbell = xhci_setup_one_noop(xhci); -- -- temp = xhci_readl(xhci, &xhci->op_regs->command); -- temp |= (CMD_RUN); -- xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", -- temp); -- xhci_writel(xhci, temp, &xhci->op_regs->command); -- /* Flush PCI posted writes */ -- temp = xhci_readl(xhci, &xhci->op_regs->command); -- xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); -- if (doorbell) -- (*doorbell)(xhci); -- -- xhci_dbg(xhci, "Finished xhci_run\n"); -- return 0; --} -- --/* -- * Stop xHCI driver. -- * -- * This function is called by the USB core when the HC driver is removed. -- * Its opposite is xhci_run(). -- * -- * Disable device contexts, disable IRQs, and quiesce the HC. -- * Reset the HC, finish any completed transactions, and cleanup memory. -- */ --void xhci_stop(struct usb_hcd *hcd) --{ -- u32 temp; -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- -- spin_lock_irq(&xhci->lock); -- xhci_halt(xhci); -- xhci_reset(xhci); -- spin_unlock_irq(&xhci->lock); -- --#if 0 /* No MSI yet */ -- xhci_cleanup_msix(xhci); --#endif --#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING -- /* Tell the event ring poll function not to reschedule */ -- xhci->zombie = 1; -- del_timer_sync(&xhci->event_ring_timer); --#endif -- -- xhci_dbg(xhci, "// Disabling event ring interrupts\n"); -- temp = xhci_readl(xhci, &xhci->op_regs->status); -- xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); -- temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); -- xhci_writel(xhci, ER_IRQ_DISABLE(temp), -- &xhci->ir_set->irq_pending); -- xhci_print_ir_set(xhci, xhci->ir_set, 0); -- -- xhci_dbg(xhci, "cleaning up memory\n"); -- xhci_mem_cleanup(xhci); -- xhci_dbg(xhci, "xhci_stop completed - status = %x\n", -- xhci_readl(xhci, &xhci->op_regs->status)); --} -- --/* -- * Shutdown HC (not bus-specific) -- * -- * This is called when the machine is rebooting or halting. We assume that the -- * machine will be powered off, and the HC's internal state will be reset. -- * Don't bother to free memory. -- */ --void xhci_shutdown(struct usb_hcd *hcd) --{ -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- -- spin_lock_irq(&xhci->lock); -- xhci_halt(xhci); -- spin_unlock_irq(&xhci->lock); -- --#if 0 -- xhci_cleanup_msix(xhci); --#endif -- -- xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n", -- xhci_readl(xhci, &xhci->op_regs->status)); --} -- --/*-------------------------------------------------------------------------*/ -- --/** -- * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and -- * HCDs. Find the index for an endpoint given its descriptor. Use the return -- * value to right shift 1 for the bitmask. -- * -- * Index = (epnum * 2) + direction - 1, -- * where direction = 0 for OUT, 1 for IN. -- * For control endpoints, the IN index is used (OUT index is unused), so -- * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2) -- */ --unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc) --{ -- unsigned int index; -- if (usb_endpoint_xfer_control(desc)) -- index = (unsigned int) (usb_endpoint_num(desc)*2); -- else -- index = (unsigned int) (usb_endpoint_num(desc)*2) + -- (usb_endpoint_dir_in(desc) ? 1 : 0) - 1; -- return index; --} -- --/* Find the flag for this endpoint (for use in the control context). Use the -- * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is -- * bit 1, etc. -- */ --unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc) --{ -- return 1 << (xhci_get_endpoint_index(desc) + 1); --} -- --/* Find the flag for this endpoint (for use in the control context). Use the -- * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is -- * bit 1, etc. -- */ --unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index) --{ -- return 1 << (ep_index + 1); --} -- --/* Compute the last valid endpoint context index. Basically, this is the -- * endpoint index plus one. For slot contexts with more than valid endpoint, -- * we find the most significant bit set in the added contexts flags. -- * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000 -- * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one. -- */ --unsigned int xhci_last_valid_endpoint(u32 added_ctxs) --{ -- return fls(added_ctxs) - 1; --} -- --/* Returns 1 if the arguments are OK; -- * returns 0 this is a root hub; returns -EINVAL for NULL pointers. -- */ --int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, -- struct usb_host_endpoint *ep, int check_ep, const char *func) { -- if (!hcd || (check_ep && !ep) || !udev) { -- printk(KERN_DEBUG "xHCI %s called with invalid args\n", -- func); -- return -EINVAL; -- } -- if (!udev->parent) { -- printk(KERN_DEBUG "xHCI %s called for root hub\n", -- func); -- return 0; -- } -- if (!udev->slot_id) { -- printk(KERN_DEBUG "xHCI %s called with unaddressed device\n", -- func); -- return -EINVAL; -- } -- return 1; --} -- --static int xhci_configure_endpoint(struct xhci_hcd *xhci, -- struct usb_device *udev, struct xhci_command *command, -- bool ctx_change, bool must_succeed); -- --/* -- * Full speed devices may have a max packet size greater than 8 bytes, but the -- * USB core doesn't know that until it reads the first 8 bytes of the -- * descriptor. If the usb_device's max packet size changes after that point, -- * we need to issue an evaluate context command and wait on it. -- */ --static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, -- unsigned int ep_index, struct urb *urb) --{ -- struct xhci_container_ctx *in_ctx; -- struct xhci_container_ctx *out_ctx; -- struct xhci_input_control_ctx *ctrl_ctx; -- struct xhci_ep_ctx *ep_ctx; -- int max_packet_size; -- int hw_max_packet_size; -- int ret = 0; -- -- out_ctx = xhci->devs[slot_id]->out_ctx; -- ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); -- hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2); -- max_packet_size = urb->dev->ep0.desc.wMaxPacketSize; -- if (hw_max_packet_size != max_packet_size) { -- xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n"); -- xhci_dbg(xhci, "Max packet size in usb_device = %d\n", -- max_packet_size); -- xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n", -- hw_max_packet_size); -- xhci_dbg(xhci, "Issuing evaluate context command.\n"); -- -- /* Set up the modified control endpoint 0 */ -- xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, -- xhci->devs[slot_id]->out_ctx, ep_index); -- in_ctx = xhci->devs[slot_id]->in_ctx; -- ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); -- ep_ctx->ep_info2 &= ~MAX_PACKET_MASK; -- ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size); -- -- /* Set up the input context flags for the command */ -- /* FIXME: This won't work if a non-default control endpoint -- * changes max packet sizes. -- */ -- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); -- ctrl_ctx->add_flags = EP0_FLAG; -- ctrl_ctx->drop_flags = 0; -- -- xhci_dbg(xhci, "Slot %d input context\n", slot_id); -- xhci_dbg_ctx(xhci, in_ctx, ep_index); -- xhci_dbg(xhci, "Slot %d output context\n", slot_id); -- xhci_dbg_ctx(xhci, out_ctx, ep_index); -- -- ret = xhci_configure_endpoint(xhci, urb->dev, NULL, -- true, false); -- -- /* Clean up the input context for later use by bandwidth -- * functions. -- */ -- ctrl_ctx->add_flags = SLOT_FLAG; -- } -- return ret; --} -- --/* -- * non-error returns are a promise to giveback() the urb later -- * we drop ownership so next owner (or urb unlink) can get it -- */ --int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) --{ -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- unsigned long flags; -- int ret = 0; -- unsigned int slot_id, ep_index; -- -- -- if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) -- return -EINVAL; -- -- slot_id = urb->dev->slot_id; -- ep_index = xhci_get_endpoint_index(&urb->ep->desc); -- -- if (!xhci->devs || !xhci->devs[slot_id]) { -- if (!in_interrupt()) -- dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); -- ret = -EINVAL; -- goto exit; -- } -- if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { -- if (!in_interrupt()) -- xhci_dbg(xhci, "urb submitted during PCI suspend\n"); -- ret = -ESHUTDOWN; -- goto exit; -- } -- if (usb_endpoint_xfer_control(&urb->ep->desc)) { -- /* Check to see if the max packet size for the default control -- * endpoint changed during FS device enumeration -- */ -- if (urb->dev->speed == USB_SPEED_FULL) { -- ret = xhci_check_maxpacket(xhci, slot_id, -- ep_index, urb); -- if (ret < 0) -- return ret; -- } -- -- /* We have a spinlock and interrupts disabled, so we must pass -- * atomic context to this function, which may allocate memory. -- */ -- spin_lock_irqsave(&xhci->lock, flags); -- if (xhci->xhc_state & XHCI_STATE_DYING) -- goto dying; -- ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, -- slot_id, ep_index); -- spin_unlock_irqrestore(&xhci->lock, flags); -- } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { -- spin_lock_irqsave(&xhci->lock, flags); -- if (xhci->xhc_state & XHCI_STATE_DYING) -- goto dying; -- ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, -- slot_id, ep_index); -- spin_unlock_irqrestore(&xhci->lock, flags); -- } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { -- spin_lock_irqsave(&xhci->lock, flags); -- if (xhci->xhc_state & XHCI_STATE_DYING) -- goto dying; -- ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, -- slot_id, ep_index); -- spin_unlock_irqrestore(&xhci->lock, flags); -- } else { -- ret = -EINVAL; -- } --exit: -- return ret; --dying: -- xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " -- "non-responsive xHCI host.\n", -- urb->ep->desc.bEndpointAddress, urb); -- spin_unlock_irqrestore(&xhci->lock, flags); -- return -ESHUTDOWN; --} -- --/* -- * Remove the URB's TD from the endpoint ring. This may cause the HC to stop -- * USB transfers, potentially stopping in the middle of a TRB buffer. The HC -- * should pick up where it left off in the TD, unless a Set Transfer Ring -- * Dequeue Pointer is issued. -- * -- * The TRBs that make up the buffers for the canceled URB will be "removed" from -- * the ring. Since the ring is a contiguous structure, they can't be physically -- * removed. Instead, there are two options: -- * -- * 1) If the HC is in the middle of processing the URB to be canceled, we -- * simply move the ring's dequeue pointer past those TRBs using the Set -- * Transfer Ring Dequeue Pointer command. This will be the common case, -- * when drivers timeout on the last submitted URB and attempt to cancel. -- * -- * 2) If the HC is in the middle of a different TD, we turn the TRBs into a -- * series of 1-TRB transfer no-op TDs. (No-ops shouldn't be chained.) The -- * HC will need to invalidate the any TRBs it has cached after the stop -- * endpoint command, as noted in the xHCI 0.95 errata. -- * -- * 3) The TD may have completed by the time the Stop Endpoint Command -- * completes, so software needs to handle that case too. -- * -- * This function should protect against the TD enqueueing code ringing the -- * doorbell while this code is waiting for a Stop Endpoint command to complete. -- * It also needs to account for multiple cancellations on happening at the same -- * time for the same endpoint. -- * -- * Note that this function can be called in any context, or so says -- * usb_hcd_unlink_urb() -- */ --int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) --{ -- unsigned long flags; -- int ret; -- u32 temp; -- struct xhci_hcd *xhci; -- struct xhci_td *td; -- unsigned int ep_index; -- struct xhci_ring *ep_ring; -- struct xhci_virt_ep *ep; -- -- xhci = hcd_to_xhci(hcd); -- spin_lock_irqsave(&xhci->lock, flags); -- /* Make sure the URB hasn't completed or been unlinked already */ -- ret = usb_hcd_check_unlink_urb(hcd, urb, status); -- if (ret || !urb->hcpriv) -- goto done; -- temp = xhci_readl(xhci, &xhci->op_regs->status); -- if (temp == 0xffffffff) { -- xhci_dbg(xhci, "HW died, freeing TD.\n"); -- td = (struct xhci_td *) urb->hcpriv; -- -- usb_hcd_unlink_urb_from_ep(hcd, urb); -- spin_unlock_irqrestore(&xhci->lock, flags); -- usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN); -- kfree(td); -- return ret; -- } -- if (xhci->xhc_state & XHCI_STATE_DYING) { -- xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " -- "non-responsive xHCI host.\n", -- urb->ep->desc.bEndpointAddress, urb); -- /* Let the stop endpoint command watchdog timer (which set this -- * state) finish cleaning up the endpoint TD lists. We must -- * have caught it in the middle of dropping a lock and giving -- * back an URB. -- */ -- goto done; -- } -- -- xhci_dbg(xhci, "Cancel URB %p\n", urb); -- xhci_dbg(xhci, "Event ring:\n"); -- xhci_debug_ring(xhci, xhci->event_ring); -- ep_index = xhci_get_endpoint_index(&urb->ep->desc); -- ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; -- ep_ring = ep->ring; -- xhci_dbg(xhci, "Endpoint ring:\n"); -- xhci_debug_ring(xhci, ep_ring); -- td = (struct xhci_td *) urb->hcpriv; -- -- list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); -- /* Queue a stop endpoint command, but only if this is -- * the first cancellation to be handled. -- */ -- if (!(ep->ep_state & EP_HALT_PENDING)) { -- ep->ep_state |= EP_HALT_PENDING; -- ep->stop_cmds_pending++; -- ep->stop_cmd_timer.expires = jiffies + -- XHCI_STOP_EP_CMD_TIMEOUT * HZ; -- add_timer(&ep->stop_cmd_timer); -- xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index); -- xhci_ring_cmd_db(xhci); -- } --done: -- spin_unlock_irqrestore(&xhci->lock, flags); -- return ret; --} -- --/* Drop an endpoint from a new bandwidth configuration for this device. -- * Only one call to this function is allowed per endpoint before -- * check_bandwidth() or reset_bandwidth() must be called. -- * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will -- * add the endpoint to the schedule with possibly new parameters denoted by a -- * different endpoint descriptor in usb_host_endpoint. -- * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is -- * not allowed. -- * -- * The USB core will not allow URBs to be queued to an endpoint that is being -- * disabled, so there's no need for mutual exclusion to protect -- * the xhci->devs[slot_id] structure. -- */ --int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, -- struct usb_host_endpoint *ep) --{ -- struct xhci_hcd *xhci; -- struct xhci_container_ctx *in_ctx, *out_ctx; -- struct xhci_input_control_ctx *ctrl_ctx; -- struct xhci_slot_ctx *slot_ctx; -- unsigned int last_ctx; -- unsigned int ep_index; -- struct xhci_ep_ctx *ep_ctx; -- u32 drop_flag; -- u32 new_add_flags, new_drop_flags, new_slot_info; -- int ret; -- -- ret = xhci_check_args(hcd, udev, ep, 1, __func__); -- if (ret <= 0) -- return ret; -- xhci = hcd_to_xhci(hcd); -- xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); -- -- drop_flag = xhci_get_endpoint_flag(&ep->desc); -- if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { -- xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", -- __func__, drop_flag); -- return 0; -- } -- -- if (!xhci->devs || !xhci->devs[udev->slot_id]) { -- xhci_warn(xhci, "xHCI %s called with unaddressed device\n", -- __func__); -- return -EINVAL; -- } -- -- in_ctx = xhci->devs[udev->slot_id]->in_ctx; -- out_ctx = xhci->devs[udev->slot_id]->out_ctx; -- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); -- ep_index = xhci_get_endpoint_index(&ep->desc); -- ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); -- /* If the HC already knows the endpoint is disabled, -- * or the HCD has noted it is disabled, ignore this request -- */ -- if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED || -- ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) { -- xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", -- __func__, ep); -- return 0; -- } -- -- ctrl_ctx->drop_flags |= drop_flag; -- new_drop_flags = ctrl_ctx->drop_flags; -- -- ctrl_ctx->add_flags &= ~drop_flag; -- new_add_flags = ctrl_ctx->add_flags; -- -- last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags); -- slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); -- /* Update the last valid endpoint context, if we deleted the last one */ -- if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) { -- slot_ctx->dev_info &= ~LAST_CTX_MASK; -- slot_ctx->dev_info |= LAST_CTX(last_ctx); -- } -- new_slot_info = slot_ctx->dev_info; -- -- xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); -- -- xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", -- (unsigned int) ep->desc.bEndpointAddress, -- udev->slot_id, -- (unsigned int) new_drop_flags, -- (unsigned int) new_add_flags, -- (unsigned int) new_slot_info); -- return 0; --} -- --/* Add an endpoint to a new possible bandwidth configuration for this device. -- * Only one call to this function is allowed per endpoint before -- * check_bandwidth() or reset_bandwidth() must be called. -- * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will -- * add the endpoint to the schedule with possibly new parameters denoted by a -- * different endpoint descriptor in usb_host_endpoint. -- * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is -- * not allowed. -- * -- * The USB core will not allow URBs to be queued to an endpoint until the -- * configuration or alt setting is installed in the device, so there's no need -- * for mutual exclusion to protect the xhci->devs[slot_id] structure. -- */ --int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, -- struct usb_host_endpoint *ep) --{ -- struct xhci_hcd *xhci; -- struct xhci_container_ctx *in_ctx, *out_ctx; -- unsigned int ep_index; -- struct xhci_ep_ctx *ep_ctx; -- struct xhci_slot_ctx *slot_ctx; -- struct xhci_input_control_ctx *ctrl_ctx; -- u32 added_ctxs; -- unsigned int last_ctx; -- u32 new_add_flags, new_drop_flags, new_slot_info; -- int ret = 0; -- -- ret = xhci_check_args(hcd, udev, ep, 1, __func__); -- if (ret <= 0) { -- /* So we won't queue a reset ep command for a root hub */ -- ep->hcpriv = NULL; -- return ret; -- } -- xhci = hcd_to_xhci(hcd); -- -- added_ctxs = xhci_get_endpoint_flag(&ep->desc); -- last_ctx = xhci_last_valid_endpoint(added_ctxs); -- if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) { -- /* FIXME when we have to issue an evaluate endpoint command to -- * deal with ep0 max packet size changing once we get the -- * descriptors -- */ -- xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n", -- __func__, added_ctxs); -- return 0; -- } -- -- if (!xhci->devs || !xhci->devs[udev->slot_id]) { -- xhci_warn(xhci, "xHCI %s called with unaddressed device\n", -- __func__); -- return -EINVAL; -- } -- -- in_ctx = xhci->devs[udev->slot_id]->in_ctx; -- out_ctx = xhci->devs[udev->slot_id]->out_ctx; -- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); -- ep_index = xhci_get_endpoint_index(&ep->desc); -- ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); -- /* If the HCD has already noted the endpoint is enabled, -- * ignore this request. -- */ -- if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) { -- xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", -- __func__, ep); -- return 0; -- } -- -- /* -- * Configuration and alternate setting changes must be done in -- * process context, not interrupt context (or so documenation -- * for usb_set_interface() and usb_set_configuration() claim). -- */ -- if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], -- udev, ep, GFP_NOIO) < 0) { -- dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", -- __func__, ep->desc.bEndpointAddress); -- return -ENOMEM; -- } -- -- ctrl_ctx->add_flags |= added_ctxs; -- new_add_flags = ctrl_ctx->add_flags; -- -- /* If xhci_endpoint_disable() was called for this endpoint, but the -- * xHC hasn't been notified yet through the check_bandwidth() call, -- * this re-adds a new state for the endpoint from the new endpoint -- * descriptors. We must drop and re-add this endpoint, so we leave the -- * drop flags alone. -- */ -- new_drop_flags = ctrl_ctx->drop_flags; -- -- slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); -- /* Update the last valid endpoint context, if we just added one past */ -- if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) { -- slot_ctx->dev_info &= ~LAST_CTX_MASK; -- slot_ctx->dev_info |= LAST_CTX(last_ctx); -- } -- new_slot_info = slot_ctx->dev_info; -- -- /* Store the usb_device pointer for later use */ -- ep->hcpriv = udev; -- -- xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", -- (unsigned int) ep->desc.bEndpointAddress, -- udev->slot_id, -- (unsigned int) new_drop_flags, -- (unsigned int) new_add_flags, -- (unsigned int) new_slot_info); -- return 0; --} -- --static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev) --{ -- struct xhci_input_control_ctx *ctrl_ctx; -- struct xhci_ep_ctx *ep_ctx; -- struct xhci_slot_ctx *slot_ctx; -- int i; -- -- /* When a device's add flag and drop flag are zero, any subsequent -- * configure endpoint command will leave that endpoint's state -- * untouched. Make sure we don't leave any old state in the input -- * endpoint contexts. -- */ -- ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); -- ctrl_ctx->drop_flags = 0; -- ctrl_ctx->add_flags = 0; -- slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); -- slot_ctx->dev_info &= ~LAST_CTX_MASK; -- /* Endpoint 0 is always valid */ -- slot_ctx->dev_info |= LAST_CTX(1); -- for (i = 1; i < 31; ++i) { -- ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i); -- ep_ctx->ep_info = 0; -- ep_ctx->ep_info2 = 0; -- ep_ctx->deq = 0; -- ep_ctx->tx_info = 0; -- } --} -- --static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, -- struct usb_device *udev, int *cmd_status) --{ -- int ret; -- -- switch (*cmd_status) { -- case COMP_ENOMEM: -- dev_warn(&udev->dev, "Not enough host controller resources " -- "for new device state.\n"); -- ret = -ENOMEM; -- /* FIXME: can we allocate more resources for the HC? */ -- break; -- case COMP_BW_ERR: -- dev_warn(&udev->dev, "Not enough bandwidth " -- "for new device state.\n"); -- ret = -ENOSPC; -- /* FIXME: can we go back to the old state? */ -- break; -- case COMP_TRB_ERR: -- /* the HCD set up something wrong */ -- dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, " -- "add flag = 1, " -- "and endpoint is not disabled.\n"); -- ret = -EINVAL; -- break; -- case COMP_SUCCESS: -- dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); -- ret = 0; -- break; -- default: -- xhci_err(xhci, "ERROR: unexpected command completion " -- "code 0x%x.\n", *cmd_status); -- ret = -EINVAL; -- break; -- } -- return ret; --} -- --static int xhci_evaluate_context_result(struct xhci_hcd *xhci, -- struct usb_device *udev, int *cmd_status) --{ -- int ret; -- struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; -- -- switch (*cmd_status) { -- case COMP_EINVAL: -- dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate " -- "context command.\n"); -- ret = -EINVAL; -- break; -- case COMP_EBADSLT: -- dev_warn(&udev->dev, "WARN: slot not enabled for" -- "evaluate context command.\n"); -- case COMP_CTX_STATE: -- dev_warn(&udev->dev, "WARN: invalid context state for " -- "evaluate context command.\n"); -- xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); -- ret = -EINVAL; -- break; -- case COMP_SUCCESS: -- dev_dbg(&udev->dev, "Successful evaluate context command\n"); -- ret = 0; -- break; -- default: -- xhci_err(xhci, "ERROR: unexpected command completion " -- "code 0x%x.\n", *cmd_status); -- ret = -EINVAL; -- break; -- } -- return ret; --} -- --/* Issue a configure endpoint command or evaluate context command -- * and wait for it to finish. -- */ --static int xhci_configure_endpoint(struct xhci_hcd *xhci, -- struct usb_device *udev, -- struct xhci_command *command, -- bool ctx_change, bool must_succeed) --{ -- int ret; -- int timeleft; -- unsigned long flags; -- struct xhci_container_ctx *in_ctx; -- struct completion *cmd_completion; -- int *cmd_status; -- struct xhci_virt_device *virt_dev; -- -- spin_lock_irqsave(&xhci->lock, flags); -- virt_dev = xhci->devs[udev->slot_id]; -- if (command) { -- in_ctx = command->in_ctx; -- cmd_completion = command->completion; -- cmd_status = &command->status; -- command->command_trb = xhci->cmd_ring->enqueue; -- list_add_tail(&command->cmd_list, &virt_dev->cmd_list); -- } else { -- in_ctx = virt_dev->in_ctx; -- cmd_completion = &virt_dev->cmd_completion; -- cmd_status = &virt_dev->cmd_status; -- } -- -- if (!ctx_change) -- ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, -- udev->slot_id, must_succeed); -- else -- ret = xhci_queue_evaluate_context(xhci, in_ctx->dma, -- udev->slot_id); -- if (ret < 0) { -- if (command) -- list_del(&command->cmd_list); -- spin_unlock_irqrestore(&xhci->lock, flags); -- xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); -- return -ENOMEM; -- } -- xhci_ring_cmd_db(xhci); -- spin_unlock_irqrestore(&xhci->lock, flags); -- -- /* Wait for the configure endpoint command to complete */ -- timeleft = wait_for_completion_interruptible_timeout( -- cmd_completion, -- USB_CTRL_SET_TIMEOUT); -- if (timeleft <= 0) { -- xhci_warn(xhci, "%s while waiting for %s command\n", -- timeleft == 0 ? "Timeout" : "Signal", -- ctx_change == 0 ? -- "configure endpoint" : -- "evaluate context"); -- /* FIXME cancel the configure endpoint command */ -- return -ETIME; -- } -- -- if (!ctx_change) -- return xhci_configure_endpoint_result(xhci, udev, cmd_status); -- return xhci_evaluate_context_result(xhci, udev, cmd_status); --} -- --/* Called after one or more calls to xhci_add_endpoint() or -- * xhci_drop_endpoint(). If this call fails, the USB core is expected -- * to call xhci_reset_bandwidth(). -- * -- * Since we are in the middle of changing either configuration or -- * installing a new alt setting, the USB core won't allow URBs to be -- * enqueued for any endpoint on the old config or interface. Nothing -- * else should be touching the xhci->devs[slot_id] structure, so we -- * don't need to take the xhci->lock for manipulating that. -- */ --int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) --{ -- int i; -- int ret = 0; -- struct xhci_hcd *xhci; -- struct xhci_virt_device *virt_dev; -- struct xhci_input_control_ctx *ctrl_ctx; -- struct xhci_slot_ctx *slot_ctx; -- -- ret = xhci_check_args(hcd, udev, NULL, 0, __func__); -- if (ret <= 0) -- return ret; -- xhci = hcd_to_xhci(hcd); -- -- if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) { -- xhci_warn(xhci, "xHCI %s called with unaddressed device\n", -- __func__); -- return -EINVAL; -- } -- xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); -- virt_dev = xhci->devs[udev->slot_id]; -- -- /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ -- ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); -- ctrl_ctx->add_flags |= SLOT_FLAG; -- ctrl_ctx->add_flags &= ~EP0_FLAG; -- ctrl_ctx->drop_flags &= ~SLOT_FLAG; -- ctrl_ctx->drop_flags &= ~EP0_FLAG; -- xhci_dbg(xhci, "New Input Control Context:\n"); -- slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); -- xhci_dbg_ctx(xhci, virt_dev->in_ctx, -- LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); -- -- ret = xhci_configure_endpoint(xhci, udev, NULL, -- false, false); -- if (ret) { -- /* Callee should call reset_bandwidth() */ -- return ret; -- } -- -- xhci_dbg(xhci, "Output context after successful config ep cmd:\n"); -- xhci_dbg_ctx(xhci, virt_dev->out_ctx, -- LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); -- -- xhci_zero_in_ctx(xhci, virt_dev); -- /* Install new rings and free or cache any old rings */ -- for (i = 1; i < 31; ++i) { -- if (!virt_dev->eps[i].new_ring) -- continue; -- /* Only cache or free the old ring if it exists. -- * It may not if this is the first add of an endpoint. -- */ -- if (virt_dev->eps[i].ring) { -- xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); -- } -- virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; -- virt_dev->eps[i].new_ring = NULL; -- } -- -- return ret; --} -- --void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) --{ -- struct xhci_hcd *xhci; -- struct xhci_virt_device *virt_dev; -- int i, ret; -- -- ret = xhci_check_args(hcd, udev, NULL, 0, __func__); -- if (ret <= 0) -- return; -- xhci = hcd_to_xhci(hcd); -- -- if (!xhci->devs || !xhci->devs[udev->slot_id]) { -- xhci_warn(xhci, "xHCI %s called with unaddressed device\n", -- __func__); -- return; -- } -- xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); -- virt_dev = xhci->devs[udev->slot_id]; -- /* Free any rings allocated for added endpoints */ -- for (i = 0; i < 31; ++i) { -- if (virt_dev->eps[i].new_ring) { -- xhci_ring_free(xhci, virt_dev->eps[i].new_ring); -- virt_dev->eps[i].new_ring = NULL; -- } -- } -- xhci_zero_in_ctx(xhci, virt_dev); --} -- --static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci, -- struct xhci_container_ctx *in_ctx, -- struct xhci_container_ctx *out_ctx, -- u32 add_flags, u32 drop_flags) --{ -- struct xhci_input_control_ctx *ctrl_ctx; -- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); -- ctrl_ctx->add_flags = add_flags; -- ctrl_ctx->drop_flags = drop_flags; -- xhci_slot_copy(xhci, in_ctx, out_ctx); -- ctrl_ctx->add_flags |= SLOT_FLAG; -- -- xhci_dbg(xhci, "Input Context:\n"); -- xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags)); --} -- --void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, -- unsigned int slot_id, unsigned int ep_index, -- struct xhci_dequeue_state *deq_state) --{ -- struct xhci_container_ctx *in_ctx; -- struct xhci_ep_ctx *ep_ctx; -- u32 added_ctxs; -- dma_addr_t addr; -- -- xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, -- xhci->devs[slot_id]->out_ctx, ep_index); -- in_ctx = xhci->devs[slot_id]->in_ctx; -- ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); -- addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg, -- deq_state->new_deq_ptr); -- if (addr == 0) { -- xhci_warn(xhci, "WARN Cannot submit config ep after " -- "reset ep command\n"); -- xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n", -- deq_state->new_deq_seg, -- deq_state->new_deq_ptr); -- return; -- } -- ep_ctx->deq = addr | deq_state->new_cycle_state; -- -- added_ctxs = xhci_get_endpoint_flag_from_index(ep_index); -- xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx, -- xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs); --} -- --void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, -- struct usb_device *udev, unsigned int ep_index) --{ -- struct xhci_dequeue_state deq_state; -- struct xhci_virt_ep *ep; -- -- xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n"); -- ep = &xhci->devs[udev->slot_id]->eps[ep_index]; -- /* We need to move the HW's dequeue pointer past this TD, -- * or it will attempt to resend it on the next doorbell ring. -- */ -- xhci_find_new_dequeue_state(xhci, udev->slot_id, -- ep_index, ep->stopped_td, -- &deq_state); -- -- /* HW with the reset endpoint quirk will use the saved dequeue state to -- * issue a configure endpoint command later. -- */ -- if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) { -- xhci_dbg(xhci, "Queueing new dequeue state\n"); -- xhci_queue_new_dequeue_state(xhci, udev->slot_id, -- ep_index, &deq_state); -- } else { -- /* Better hope no one uses the input context between now and the -- * reset endpoint completion! -- */ -- xhci_dbg(xhci, "Setting up input context for " -- "configure endpoint command\n"); -- xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id, -- ep_index, &deq_state); -- } --} -- --/* Deal with stalled endpoints. The core should have sent the control message -- * to clear the halt condition. However, we need to make the xHCI hardware -- * reset its sequence number, since a device will expect a sequence number of -- * zero after the halt condition is cleared. -- * Context: in_interrupt -- */ --void xhci_endpoint_reset(struct usb_hcd *hcd, -- struct usb_host_endpoint *ep) --{ -- struct xhci_hcd *xhci; -- struct usb_device *udev; -- unsigned int ep_index; -- unsigned long flags; -- int ret; -- struct xhci_virt_ep *virt_ep; -- -- xhci = hcd_to_xhci(hcd); -- udev = (struct usb_device *) ep->hcpriv; -- /* Called with a root hub endpoint (or an endpoint that wasn't added -- * with xhci_add_endpoint() -- */ -- if (!ep->hcpriv) -- return; -- ep_index = xhci_get_endpoint_index(&ep->desc); -- virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index]; -- if (!virt_ep->stopped_td) { -- xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n", -- ep->desc.bEndpointAddress); -- return; -- } -- if (usb_endpoint_xfer_control(&ep->desc)) { -- xhci_dbg(xhci, "Control endpoint stall already handled.\n"); -- return; -- } -- -- xhci_dbg(xhci, "Queueing reset endpoint command\n"); -- spin_lock_irqsave(&xhci->lock, flags); -- ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index); -- /* -- * Can't change the ring dequeue pointer until it's transitioned to the -- * stopped state, which is only upon a successful reset endpoint -- * command. Better hope that last command worked! -- */ -- if (!ret) { -- xhci_cleanup_stalled_ring(xhci, udev, ep_index); -- kfree(virt_ep->stopped_td); -- xhci_ring_cmd_db(xhci); -- } -- spin_unlock_irqrestore(&xhci->lock, flags); -- -- if (ret) -- xhci_warn(xhci, "FIXME allocate a new ring segment\n"); --} -- --/* -- * This submits a Reset Device Command, which will set the device state to 0, -- * set the device address to 0, and disable all the endpoints except the default -- * control endpoint. The USB core should come back and call -- * xhci_address_device(), and then re-set up the configuration. If this is -- * called because of a usb_reset_and_verify_device(), then the old alternate -- * settings will be re-installed through the normal bandwidth allocation -- * functions. -- * -- * Wait for the Reset Device command to finish. Remove all structures -- * associated with the endpoints that were disabled. Clear the input device -- * structure? Cache the rings? Reset the control endpoint 0 max packet size? -- */ --int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev) --{ -- int ret, i; -- unsigned long flags; -- struct xhci_hcd *xhci; -- unsigned int slot_id; -- struct xhci_virt_device *virt_dev; -- struct xhci_command *reset_device_cmd; -- int timeleft; -- int last_freed_endpoint; -- -- ret = xhci_check_args(hcd, udev, NULL, 0, __func__); -- if (ret <= 0) -- return ret; -- xhci = hcd_to_xhci(hcd); -- slot_id = udev->slot_id; -- virt_dev = xhci->devs[slot_id]; -- if (!virt_dev) { -- xhci_dbg(xhci, "%s called with invalid slot ID %u\n", -- __func__, slot_id); -- return -EINVAL; -- } -- -- xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); -- /* Allocate the command structure that holds the struct completion. -- * Assume we're in process context, since the normal device reset -- * process has to wait for the device anyway. Storage devices are -- * reset as part of error handling, so use GFP_NOIO instead of -- * GFP_KERNEL. -- */ -- reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); -- if (!reset_device_cmd) { -- xhci_dbg(xhci, "Couldn't allocate command structure.\n"); -- return -ENOMEM; -- } -- -- /* Attempt to submit the Reset Device command to the command ring */ -- spin_lock_irqsave(&xhci->lock, flags); -- reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; -- list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); -- ret = xhci_queue_reset_device(xhci, slot_id); -- if (ret) { -- xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); -- list_del(&reset_device_cmd->cmd_list); -- spin_unlock_irqrestore(&xhci->lock, flags); -- goto command_cleanup; -- } -- xhci_ring_cmd_db(xhci); -- spin_unlock_irqrestore(&xhci->lock, flags); -- -- /* Wait for the Reset Device command to finish */ -- timeleft = wait_for_completion_interruptible_timeout( -- reset_device_cmd->completion, -- USB_CTRL_SET_TIMEOUT); -- if (timeleft <= 0) { -- xhci_warn(xhci, "%s while waiting for reset device command\n", -- timeleft == 0 ? "Timeout" : "Signal"); -- spin_lock_irqsave(&xhci->lock, flags); -- /* The timeout might have raced with the event ring handler, so -- * only delete from the list if the item isn't poisoned. -- */ -- if (reset_device_cmd->cmd_list.next != LIST_POISON1) -- list_del(&reset_device_cmd->cmd_list); -- spin_unlock_irqrestore(&xhci->lock, flags); -- ret = -ETIME; -- goto command_cleanup; -- } -- -- /* The Reset Device command can't fail, according to the 0.95/0.96 spec, -- * unless we tried to reset a slot ID that wasn't enabled, -- * or the device wasn't in the addressed or configured state. -- */ -- ret = reset_device_cmd->status; -- switch (ret) { -- case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */ -- case COMP_CTX_STATE: /* 0.96 completion code for same thing */ -- xhci_info(xhci, "Can't reset device (slot ID %u) in %s state\n", -- slot_id, -- xhci_get_slot_state(xhci, virt_dev->out_ctx)); -- xhci_info(xhci, "Not freeing device rings.\n"); -- /* Don't treat this as an error. May change my mind later. */ -- ret = 0; -- goto command_cleanup; -- case COMP_SUCCESS: -- xhci_dbg(xhci, "Successful reset device command.\n"); -- break; -- default: -- if (xhci_is_vendor_info_code(xhci, ret)) -- break; -- xhci_warn(xhci, "Unknown completion code %u for " -- "reset device command.\n", ret); -- ret = -EINVAL; -- goto command_cleanup; -- } -- -- /* Everything but endpoint 0 is disabled, so free or cache the rings. */ -- last_freed_endpoint = 1; -- for (i = 1; i < 31; ++i) { -- if (!virt_dev->eps[i].ring) -- continue; -- xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); -- last_freed_endpoint = i; -- } -- xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); -- xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); -- ret = 0; -- --command_cleanup: -- xhci_free_command(xhci, reset_device_cmd); -- return ret; --} -- --/* -- * At this point, the struct usb_device is about to go away, the device has -- * disconnected, and all traffic has been stopped and the endpoints have been -- * disabled. Free any HC data structures associated with that device. -- */ --void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) --{ -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- struct xhci_virt_device *virt_dev; -- unsigned long flags; -- u32 state; -- int i; -- -- if (udev->slot_id == 0) -- return; -- virt_dev = xhci->devs[udev->slot_id]; -- if (!virt_dev) -- return; -- -- /* Stop any wayward timer functions (which may grab the lock) */ -- for (i = 0; i < 31; ++i) { -- virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING; -- del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); -- } -- -- spin_lock_irqsave(&xhci->lock, flags); -- /* Don't disable the slot if the host controller is dead. */ -- state = xhci_readl(xhci, &xhci->op_regs->status); -- if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { -- xhci_free_virt_device(xhci, udev->slot_id); -- spin_unlock_irqrestore(&xhci->lock, flags); -- return; -- } -- -- if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) { -- spin_unlock_irqrestore(&xhci->lock, flags); -- xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); -- return; -- } -- xhci_ring_cmd_db(xhci); -- spin_unlock_irqrestore(&xhci->lock, flags); -- /* -- * Event command completion handler will free any data structures -- * associated with the slot. XXX Can free sleep? -- */ --} -- --/* -- * Returns 0 if the xHC ran out of device slots, the Enable Slot command -- * timed out, or allocating memory failed. Returns 1 on success. -- */ --int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) --{ -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- unsigned long flags; -- int timeleft; -- int ret; -- -- spin_lock_irqsave(&xhci->lock, flags); -- ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); -- if (ret) { -- spin_unlock_irqrestore(&xhci->lock, flags); -- xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); -- return 0; -- } -- xhci_ring_cmd_db(xhci); -- spin_unlock_irqrestore(&xhci->lock, flags); -- -- /* XXX: how much time for xHC slot assignment? */ -- timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, -- USB_CTRL_SET_TIMEOUT); -- if (timeleft <= 0) { -- xhci_warn(xhci, "%s while waiting for a slot\n", -- timeleft == 0 ? "Timeout" : "Signal"); -- /* FIXME cancel the enable slot request */ -- return 0; -- } -- -- if (!xhci->slot_id) { -- xhci_err(xhci, "Error while assigning device slot ID\n"); -- return 0; -- } -- /* xhci_alloc_virt_device() does not touch rings; no need to lock */ -- if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) { -- /* Disable slot, if we can do it without mem alloc */ -- xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); -- spin_lock_irqsave(&xhci->lock, flags); -- if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) -- xhci_ring_cmd_db(xhci); -- spin_unlock_irqrestore(&xhci->lock, flags); -- return 0; -- } -- udev->slot_id = xhci->slot_id; -- /* Is this a LS or FS device under a HS hub? */ -- /* Hub or peripherial? */ -- return 1; --} -- --/* -- * Issue an Address Device command (which will issue a SetAddress request to -- * the device). -- * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so -- * we should only issue and wait on one address command at the same time. -- * -- * We add one to the device address issued by the hardware because the USB core -- * uses address 1 for the root hubs (even though they're not really devices). -- */ --int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) --{ -- unsigned long flags; -- int timeleft; -- struct xhci_virt_device *virt_dev; -- int ret = 0; -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- struct xhci_slot_ctx *slot_ctx; -- struct xhci_input_control_ctx *ctrl_ctx; -- u64 temp_64; -- -- if (!udev->slot_id) { -- xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); -- return -EINVAL; -- } -- -- virt_dev = xhci->devs[udev->slot_id]; -- -- /* If this is a Set Address to an unconfigured device, setup ep 0 */ -- if (!udev->config) -- xhci_setup_addressable_virt_dev(xhci, udev); -- /* Otherwise, assume the core has the device configured how it wants */ -- xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); -- xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); -- -- spin_lock_irqsave(&xhci->lock, flags); -- ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, -- udev->slot_id); -- if (ret) { -- spin_unlock_irqrestore(&xhci->lock, flags); -- xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); -- return ret; -- } -- xhci_ring_cmd_db(xhci); -- spin_unlock_irqrestore(&xhci->lock, flags); -- -- /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ -- timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, -- USB_CTRL_SET_TIMEOUT); -- /* FIXME: From section 4.3.4: "Software shall be responsible for timing -- * the SetAddress() "recovery interval" required by USB and aborting the -- * command on a timeout. -- */ -- if (timeleft <= 0) { -- xhci_warn(xhci, "%s while waiting for a slot\n", -- timeleft == 0 ? "Timeout" : "Signal"); -- /* FIXME cancel the address device command */ -- return -ETIME; -- } -- -- switch (virt_dev->cmd_status) { -- case COMP_CTX_STATE: -- case COMP_EBADSLT: -- xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n", -- udev->slot_id); -- ret = -EINVAL; -- break; -- case COMP_TX_ERR: -- dev_warn(&udev->dev, "Device not responding to set address.\n"); -- ret = -EPROTO; -- break; -- case COMP_SUCCESS: -- xhci_dbg(xhci, "Successful Address Device command\n"); -- break; -- default: -- xhci_err(xhci, "ERROR: unexpected command completion " -- "code 0x%x.\n", virt_dev->cmd_status); -- xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); -- xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); -- ret = -EINVAL; -- break; -- } -- if (ret) { -- return ret; -- } -- temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); -- xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64); -- xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n", -- udev->slot_id, -- &xhci->dcbaa->dev_context_ptrs[udev->slot_id], -- (unsigned long long) -- xhci->dcbaa->dev_context_ptrs[udev->slot_id]); -- xhci_dbg(xhci, "Output Context DMA address = %#08llx\n", -- (unsigned long long)virt_dev->out_ctx->dma); -- xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); -- xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); -- xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); -- xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); -- /* -- * USB core uses address 1 for the roothubs, so we add one to the -- * address given back to us by the HC. -- */ -- slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); -- udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; -- /* Zero the input context control for later use */ -- ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); -- ctrl_ctx->add_flags = 0; -- ctrl_ctx->drop_flags = 0; -- -- xhci_dbg(xhci, "Device address = %d\n", udev->devnum); -- /* XXX Meh, not sure if anyone else but choose_address uses this. */ -- set_bit(udev->devnum, udev->bus->devmap.devicemap); -- -- return 0; --} -- --/* Once a hub descriptor is fetched for a device, we need to update the xHC's -- * internal data structures for the device. -- */ --int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, -- struct usb_tt *tt, gfp_t mem_flags) --{ -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- struct xhci_virt_device *vdev; -- struct xhci_command *config_cmd; -- struct xhci_input_control_ctx *ctrl_ctx; -- struct xhci_slot_ctx *slot_ctx; -- unsigned long flags; -- unsigned think_time; -- int ret; -- -- /* Ignore root hubs */ -- if (!hdev->parent) -- return 0; -- -- vdev = xhci->devs[hdev->slot_id]; -- if (!vdev) { -- xhci_warn(xhci, "Cannot update hub desc for unknown device.\n"); -- return -EINVAL; -- } -- config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); -- if (!config_cmd) { -- xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); -- return -ENOMEM; -- } -- -- spin_lock_irqsave(&xhci->lock, flags); -- xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx); -- ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); -- ctrl_ctx->add_flags |= SLOT_FLAG; -- slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx); -- slot_ctx->dev_info |= DEV_HUB; -- if (tt->multi) -- slot_ctx->dev_info |= DEV_MTT; -- if (xhci->hci_version > 0x95) { -- xhci_dbg(xhci, "xHCI version %x needs hub " -- "TT think time and number of ports\n", -- (unsigned int) xhci->hci_version); -- slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild); -- /* Set TT think time - convert from ns to FS bit times. -- * 0 = 8 FS bit times, 1 = 16 FS bit times, -- * 2 = 24 FS bit times, 3 = 32 FS bit times. -- */ -- think_time = tt->think_time; -- if (think_time != 0) -- think_time = (think_time / 666) - 1; -- slot_ctx->tt_info |= TT_THINK_TIME(think_time); -- } else { -- xhci_dbg(xhci, "xHCI version %x doesn't need hub " -- "TT think time or number of ports\n", -- (unsigned int) xhci->hci_version); -- } -- slot_ctx->dev_state = 0; -- spin_unlock_irqrestore(&xhci->lock, flags); -- -- xhci_dbg(xhci, "Set up %s for hub device.\n", -- (xhci->hci_version > 0x95) ? -- "configure endpoint" : "evaluate context"); -- xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id); -- xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0); -- -- /* Issue and wait for the configure endpoint or -- * evaluate context command. -- */ -- if (xhci->hci_version > 0x95) -- ret = xhci_configure_endpoint(xhci, hdev, config_cmd, -- false, false); -- else -- ret = xhci_configure_endpoint(xhci, hdev, config_cmd, -- true, false); -- -- xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id); -- xhci_dbg_ctx(xhci, vdev->out_ctx, 0); -- -- xhci_free_command(xhci, config_cmd); -- return ret; --} -- --int xhci_get_frame(struct usb_hcd *hcd) --{ -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- /* EHCI mods by the periodic size. Why? */ -- return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3; --} -- --MODULE_DESCRIPTION(DRIVER_DESC); --MODULE_AUTHOR(DRIVER_AUTHOR); --MODULE_LICENSE("GPL"); -- --static int __init xhci_hcd_init(void) --{ --#ifdef CONFIG_PCI -- int retval = 0; -- -- retval = xhci_register_pci(); -- -- if (retval < 0) { -- printk(KERN_DEBUG "Problem registering PCI driver."); -- return retval; -- } --#endif -- /* -- * Check the compiler generated sizes of structures that must be laid -- * out in specific ways for hardware access. -- */ -- BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); -- BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8); -- BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8); -- /* xhci_device_control has eight fields, and also -- * embeds one xhci_slot_ctx and 31 xhci_ep_ctx -- */ -- BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); -- BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); -- BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); -- BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8); -- BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); -- /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ -- BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); -- BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); -- return 0; --} --module_init(xhci_hcd_init); -- --static void __exit xhci_hcd_cleanup(void) --{ --#ifdef CONFIG_PCI -- xhci_unregister_pci(); --#endif --} --module_exit(xhci_hcd_cleanup); ---- /dev/null -+++ b/drivers/usb/host/xhci.c -@@ -0,0 +1,1916 @@ -+/* -+ * xHCI host controller driver -+ * -+ * Copyright (C) 2008 Intel Corp. -+ * -+ * Author: Sarah Sharp -+ * Some code borrowed from the Linux EHCI driver. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software Foundation, -+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include <linux/irq.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+ -+#include "xhci.h" -+ -+#define DRIVER_AUTHOR "Sarah Sharp" -+#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" -+ -+/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */ -+static int link_quirk; -+module_param(link_quirk, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); -+ -+/* TODO: copied from ehci-hcd.c - can this be refactored? */ -+/* -+ * handshake - spin reading hc until handshake completes or fails -+ * @ptr: address of hc register to be read -+ * @mask: bits to look at in result of read -+ * @done: value of those bits when handshake succeeds -+ * @usec: timeout in microseconds -+ * -+ * Returns negative errno, or zero on success -+ * -+ * Success happens when the "mask" bits have the specified value (hardware -+ * handshake done). There are two failure modes: "usec" have passed (major -+ * hardware flakeout), or the register reads as all-ones (hardware removed). -+ */ -+static int handshake(struct xhci_hcd *xhci, void __iomem *ptr, -+ u32 mask, u32 done, int usec) -+{ -+ u32 result; -+ -+ do { -+ result = xhci_readl(xhci, ptr); -+ if (result == ~(u32)0) /* card removed */ -+ return -ENODEV; -+ result &= mask; -+ if (result == done) -+ return 0; -+ udelay(1); -+ usec--; -+ } while (usec > 0); -+ return -ETIMEDOUT; -+} -+ -+/* -+ * Disable interrupts and begin the xHCI halting process. -+ */ -+void xhci_quiesce(struct xhci_hcd *xhci) -+{ -+ u32 halted; -+ u32 cmd; -+ u32 mask; -+ -+ mask = ~(XHCI_IRQS); -+ halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT; -+ if (!halted) -+ mask &= ~CMD_RUN; -+ -+ cmd = xhci_readl(xhci, &xhci->op_regs->command); -+ cmd &= mask; -+ xhci_writel(xhci, cmd, &xhci->op_regs->command); -+} -+ -+/* -+ * Force HC into halt state. -+ * -+ * Disable any IRQs and clear the run/stop bit. -+ * HC will complete any current and actively pipelined transactions, and -+ * should halt within 16 microframes of the run/stop bit being cleared. -+ * Read HC Halted bit in the status register to see when the HC is finished. -+ * XXX: shouldn't we set HC_STATE_HALT here somewhere? -+ */ -+int xhci_halt(struct xhci_hcd *xhci) -+{ -+ xhci_dbg(xhci, "// Halt the HC\n"); -+ xhci_quiesce(xhci); -+ -+ return handshake(xhci, &xhci->op_regs->status, -+ STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); -+} -+ -+/* -+ * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. -+ * -+ * This resets pipelines, timers, counters, state machines, etc. -+ * Transactions will be terminated immediately, and operational registers -+ * will be set to their defaults. -+ */ -+int xhci_reset(struct xhci_hcd *xhci) -+{ -+ u32 command; -+ u32 state; -+ -+ state = xhci_readl(xhci, &xhci->op_regs->status); -+ if ((state & STS_HALT) == 0) { -+ xhci_warn(xhci, "Host controller not halted, aborting reset.\n"); -+ return 0; -+ } -+ -+ xhci_dbg(xhci, "// Reset the HC\n"); -+ command = xhci_readl(xhci, &xhci->op_regs->command); -+ command |= CMD_RESET; -+ xhci_writel(xhci, command, &xhci->op_regs->command); -+ /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ -+ xhci_to_hcd(xhci)->state = HC_STATE_HALT; -+ -+ return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); -+} -+ -+ -+#if 0 -+/* Set up MSI-X table for entry 0 (may claim other entries later) */ -+static int xhci_setup_msix(struct xhci_hcd *xhci) -+{ -+ int ret; -+ struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); -+ -+ xhci->msix_count = 0; -+ /* XXX: did I do this right? ixgbe does kcalloc for more than one */ -+ xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL); -+ if (!xhci->msix_entries) { -+ xhci_err(xhci, "Failed to allocate MSI-X entries\n"); -+ return -ENOMEM; -+ } -+ xhci->msix_entries[0].entry = 0; -+ -+ ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count); -+ if (ret) { -+ xhci_err(xhci, "Failed to enable MSI-X\n"); -+ goto free_entries; -+ } -+ -+ /* -+ * Pass the xhci pointer value as the request_irq "cookie". -+ * If more irqs are added, this will need to be unique for each one. -+ */ -+ ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0, -+ "xHCI", xhci_to_hcd(xhci)); -+ if (ret) { -+ xhci_err(xhci, "Failed to allocate MSI-X interrupt\n"); -+ goto disable_msix; -+ } -+ xhci_dbg(xhci, "Finished setting up MSI-X\n"); -+ return 0; -+ -+disable_msix: -+ pci_disable_msix(pdev); -+free_entries: -+ kfree(xhci->msix_entries); -+ xhci->msix_entries = NULL; -+ return ret; -+} -+ -+/* XXX: code duplication; can xhci_setup_msix call this? */ -+/* Free any IRQs and disable MSI-X */ -+static void xhci_cleanup_msix(struct xhci_hcd *xhci) -+{ -+ struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); -+ if (!xhci->msix_entries) -+ return; -+ -+ free_irq(xhci->msix_entries[0].vector, xhci); -+ pci_disable_msix(pdev); -+ kfree(xhci->msix_entries); -+ xhci->msix_entries = NULL; -+ xhci_dbg(xhci, "Finished cleaning up MSI-X\n"); -+} -+#endif -+ -+/* -+ * Initialize memory for HCD and xHC (one-time init). -+ * -+ * Program the PAGESIZE register, initialize the device context array, create -+ * device contexts (?), set up a command ring segment (or two?), create event -+ * ring (one for now). -+ */ -+int xhci_init(struct usb_hcd *hcd) -+{ -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ int retval = 0; -+ -+ xhci_dbg(xhci, "xhci_init\n"); -+ spin_lock_init(&xhci->lock); -+ if (link_quirk) { -+ xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); -+ xhci->quirks |= XHCI_LINK_TRB_QUIRK; -+ } else { -+ xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n"); -+ } -+ retval = xhci_mem_init(xhci, GFP_KERNEL); -+ xhci_dbg(xhci, "Finished xhci_init\n"); -+ -+ return retval; -+} -+ -+/* -+ * Called in interrupt context when there might be work -+ * queued on the event ring -+ * -+ * xhci->lock must be held by caller. -+ */ -+static void xhci_work(struct xhci_hcd *xhci) -+{ -+ u32 temp; -+ u64 temp_64; -+ -+ /* -+ * Clear the op reg interrupt status first, -+ * so we can receive interrupts from other MSI-X interrupters. -+ * Write 1 to clear the interrupt status. -+ */ -+ temp = xhci_readl(xhci, &xhci->op_regs->status); -+ temp |= STS_EINT; -+ xhci_writel(xhci, temp, &xhci->op_regs->status); -+ /* FIXME when MSI-X is supported and there are multiple vectors */ -+ /* Clear the MSI-X event interrupt status */ -+ -+ /* Acknowledge the interrupt */ -+ temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); -+ temp |= 0x3; -+ xhci_writel(xhci, temp, &xhci->ir_set->irq_pending); -+ /* Flush posted writes */ -+ xhci_readl(xhci, &xhci->ir_set->irq_pending); -+ -+ if (xhci->xhc_state & XHCI_STATE_DYING) -+ xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " -+ "Shouldn't IRQs be disabled?\n"); -+ else -+ /* FIXME this should be a delayed service routine -+ * that clears the EHB. -+ */ -+ xhci_handle_event(xhci); -+ -+ /* Clear the event handler busy flag (RW1C); the event ring should be empty. */ -+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); -+ xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); -+ /* Flush posted writes -- FIXME is this necessary? */ -+ xhci_readl(xhci, &xhci->ir_set->irq_pending); -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+/* -+ * xHCI spec says we can get an interrupt, and if the HC has an error condition, -+ * we might get bad data out of the event ring. Section 4.10.2.7 has a list of -+ * indicators of an event TRB error, but we check the status *first* to be safe. -+ */ -+irqreturn_t xhci_irq(struct usb_hcd *hcd) -+{ -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ u32 temp, temp2; -+ union xhci_trb *trb; -+ -+ spin_lock(&xhci->lock); -+ trb = xhci->event_ring->dequeue; -+ /* Check if the xHC generated the interrupt, or the irq is shared */ -+ temp = xhci_readl(xhci, &xhci->op_regs->status); -+ temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); -+ if (temp == 0xffffffff && temp2 == 0xffffffff) -+ goto hw_died; -+ -+ if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { -+ spin_unlock(&xhci->lock); -+ return IRQ_NONE; -+ } -+ xhci_dbg(xhci, "op reg status = %08x\n", temp); -+ xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2); -+ xhci_dbg(xhci, "Event ring dequeue ptr:\n"); -+ xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", -+ (unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb), -+ lower_32_bits(trb->link.segment_ptr), -+ upper_32_bits(trb->link.segment_ptr), -+ (unsigned int) trb->link.intr_target, -+ (unsigned int) trb->link.control); -+ -+ if (temp & STS_FATAL) { -+ xhci_warn(xhci, "WARNING: Host System Error\n"); -+ xhci_halt(xhci); -+hw_died: -+ xhci_to_hcd(xhci)->state = HC_STATE_HALT; -+ spin_unlock(&xhci->lock); -+ return -ESHUTDOWN; -+ } -+ -+ xhci_work(xhci); -+ spin_unlock(&xhci->lock); -+ -+ return IRQ_HANDLED; -+} -+ -+#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING -+void xhci_event_ring_work(unsigned long arg) -+{ -+ unsigned long flags; -+ int temp; -+ u64 temp_64; -+ struct xhci_hcd *xhci = (struct xhci_hcd *) arg; -+ int i, j; -+ -+ xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies); -+ -+ spin_lock_irqsave(&xhci->lock, flags); -+ temp = xhci_readl(xhci, &xhci->op_regs->status); -+ xhci_dbg(xhci, "op reg status = 0x%x\n", temp); -+ if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { -+ xhci_dbg(xhci, "HW died, polling stopped.\n"); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ return; -+ } -+ -+ temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); -+ xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); -+ xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled); -+ xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask); -+ xhci->error_bitmask = 0; -+ xhci_dbg(xhci, "Event ring:\n"); -+ xhci_debug_segment(xhci, xhci->event_ring->deq_seg); -+ xhci_dbg_ring_ptrs(xhci, xhci->event_ring); -+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); -+ temp_64 &= ~ERST_PTR_MASK; -+ xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); -+ xhci_dbg(xhci, "Command ring:\n"); -+ xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg); -+ xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); -+ xhci_dbg_cmd_ptrs(xhci); -+ for (i = 0; i < MAX_HC_SLOTS; ++i) { -+ if (!xhci->devs[i]) -+ continue; -+ for (j = 0; j < 31; ++j) { -+ struct xhci_ring *ring = xhci->devs[i]->eps[j].ring; -+ if (!ring) -+ continue; -+ xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j); -+ xhci_debug_segment(xhci, ring->deq_seg); -+ } -+ } -+ -+ if (xhci->noops_submitted != NUM_TEST_NOOPS) -+ if (xhci_setup_one_noop(xhci)) -+ xhci_ring_cmd_db(xhci); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ -+ if (!xhci->zombie) -+ mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ); -+ else -+ xhci_dbg(xhci, "Quit polling the event ring.\n"); -+} -+#endif -+ -+/* -+ * Start the HC after it was halted. -+ * -+ * This function is called by the USB core when the HC driver is added. -+ * Its opposite is xhci_stop(). -+ * -+ * xhci_init() must be called once before this function can be called. -+ * Reset the HC, enable device slot contexts, program DCBAAP, and -+ * set command ring pointer and event ring pointer. -+ * -+ * Setup MSI-X vectors and enable interrupts. -+ */ -+int xhci_run(struct usb_hcd *hcd) -+{ -+ u32 temp; -+ u64 temp_64; -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ void (*doorbell)(struct xhci_hcd *) = NULL; -+ -+ hcd->uses_new_polling = 1; -+ hcd->poll_rh = 0; -+ -+ xhci_dbg(xhci, "xhci_run\n"); -+#if 0 /* FIXME: MSI not setup yet */ -+ /* Do this at the very last minute */ -+ ret = xhci_setup_msix(xhci); -+ if (!ret) -+ return ret; -+ -+ return -ENOSYS; -+#endif -+#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING -+ init_timer(&xhci->event_ring_timer); -+ xhci->event_ring_timer.data = (unsigned long) xhci; -+ xhci->event_ring_timer.function = xhci_event_ring_work; -+ /* Poll the event ring */ -+ xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ; -+ xhci->zombie = 0; -+ xhci_dbg(xhci, "Setting event ring polling timer\n"); -+ add_timer(&xhci->event_ring_timer); -+#endif -+ -+ xhci_dbg(xhci, "Command ring memory map follows:\n"); -+ xhci_debug_ring(xhci, xhci->cmd_ring); -+ xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); -+ xhci_dbg_cmd_ptrs(xhci); -+ -+ xhci_dbg(xhci, "ERST memory map follows:\n"); -+ xhci_dbg_erst(xhci, &xhci->erst); -+ xhci_dbg(xhci, "Event ring:\n"); -+ xhci_debug_ring(xhci, xhci->event_ring); -+ xhci_dbg_ring_ptrs(xhci, xhci->event_ring); -+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); -+ temp_64 &= ~ERST_PTR_MASK; -+ xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); -+ -+ xhci_dbg(xhci, "// Set the interrupt modulation register\n"); -+ temp = xhci_readl(xhci, &xhci->ir_set->irq_control); -+ temp &= ~ER_IRQ_INTERVAL_MASK; -+ temp |= (u32) 160; -+ xhci_writel(xhci, temp, &xhci->ir_set->irq_control); -+ -+ /* Set the HCD state before we enable the irqs */ -+ hcd->state = HC_STATE_RUNNING; -+ temp = xhci_readl(xhci, &xhci->op_regs->command); -+ temp |= (CMD_EIE); -+ xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n", -+ temp); -+ xhci_writel(xhci, temp, &xhci->op_regs->command); -+ -+ temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); -+ xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n", -+ xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); -+ xhci_writel(xhci, ER_IRQ_ENABLE(temp), -+ &xhci->ir_set->irq_pending); -+ xhci_print_ir_set(xhci, xhci->ir_set, 0); -+ -+ if (NUM_TEST_NOOPS > 0) -+ doorbell = xhci_setup_one_noop(xhci); -+ -+ temp = xhci_readl(xhci, &xhci->op_regs->command); -+ temp |= (CMD_RUN); -+ xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", -+ temp); -+ xhci_writel(xhci, temp, &xhci->op_regs->command); -+ /* Flush PCI posted writes */ -+ temp = xhci_readl(xhci, &xhci->op_regs->command); -+ xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); -+ if (doorbell) -+ (*doorbell)(xhci); -+ -+ xhci_dbg(xhci, "Finished xhci_run\n"); -+ return 0; -+} -+ -+/* -+ * Stop xHCI driver. -+ * -+ * This function is called by the USB core when the HC driver is removed. -+ * Its opposite is xhci_run(). -+ * -+ * Disable device contexts, disable IRQs, and quiesce the HC. -+ * Reset the HC, finish any completed transactions, and cleanup memory. -+ */ -+void xhci_stop(struct usb_hcd *hcd) -+{ -+ u32 temp; -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ -+ spin_lock_irq(&xhci->lock); -+ xhci_halt(xhci); -+ xhci_reset(xhci); -+ spin_unlock_irq(&xhci->lock); -+ -+#if 0 /* No MSI yet */ -+ xhci_cleanup_msix(xhci); -+#endif -+#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING -+ /* Tell the event ring poll function not to reschedule */ -+ xhci->zombie = 1; -+ del_timer_sync(&xhci->event_ring_timer); -+#endif -+ -+ xhci_dbg(xhci, "// Disabling event ring interrupts\n"); -+ temp = xhci_readl(xhci, &xhci->op_regs->status); -+ xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); -+ temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); -+ xhci_writel(xhci, ER_IRQ_DISABLE(temp), -+ &xhci->ir_set->irq_pending); -+ xhci_print_ir_set(xhci, xhci->ir_set, 0); -+ -+ xhci_dbg(xhci, "cleaning up memory\n"); -+ xhci_mem_cleanup(xhci); -+ xhci_dbg(xhci, "xhci_stop completed - status = %x\n", -+ xhci_readl(xhci, &xhci->op_regs->status)); -+} -+ -+/* -+ * Shutdown HC (not bus-specific) -+ * -+ * This is called when the machine is rebooting or halting. We assume that the -+ * machine will be powered off, and the HC's internal state will be reset. -+ * Don't bother to free memory. -+ */ -+void xhci_shutdown(struct usb_hcd *hcd) -+{ -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ -+ spin_lock_irq(&xhci->lock); -+ xhci_halt(xhci); -+ spin_unlock_irq(&xhci->lock); -+ -+#if 0 -+ xhci_cleanup_msix(xhci); -+#endif -+ -+ xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n", -+ xhci_readl(xhci, &xhci->op_regs->status)); -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+/** -+ * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and -+ * HCDs. Find the index for an endpoint given its descriptor. Use the return -+ * value to right shift 1 for the bitmask. -+ * -+ * Index = (epnum * 2) + direction - 1, -+ * where direction = 0 for OUT, 1 for IN. -+ * For control endpoints, the IN index is used (OUT index is unused), so -+ * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2) -+ */ -+unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc) -+{ -+ unsigned int index; -+ if (usb_endpoint_xfer_control(desc)) -+ index = (unsigned int) (usb_endpoint_num(desc)*2); -+ else -+ index = (unsigned int) (usb_endpoint_num(desc)*2) + -+ (usb_endpoint_dir_in(desc) ? 1 : 0) - 1; -+ return index; -+} -+ -+/* Find the flag for this endpoint (for use in the control context). Use the -+ * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is -+ * bit 1, etc. -+ */ -+unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc) -+{ -+ return 1 << (xhci_get_endpoint_index(desc) + 1); -+} -+ -+/* Find the flag for this endpoint (for use in the control context). Use the -+ * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is -+ * bit 1, etc. -+ */ -+unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index) -+{ -+ return 1 << (ep_index + 1); -+} -+ -+/* Compute the last valid endpoint context index. Basically, this is the -+ * endpoint index plus one. For slot contexts with more than valid endpoint, -+ * we find the most significant bit set in the added contexts flags. -+ * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000 -+ * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one. -+ */ -+unsigned int xhci_last_valid_endpoint(u32 added_ctxs) -+{ -+ return fls(added_ctxs) - 1; -+} -+ -+/* Returns 1 if the arguments are OK; -+ * returns 0 this is a root hub; returns -EINVAL for NULL pointers. -+ */ -+int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, -+ struct usb_host_endpoint *ep, int check_ep, const char *func) { -+ if (!hcd || (check_ep && !ep) || !udev) { -+ printk(KERN_DEBUG "xHCI %s called with invalid args\n", -+ func); -+ return -EINVAL; -+ } -+ if (!udev->parent) { -+ printk(KERN_DEBUG "xHCI %s called for root hub\n", -+ func); -+ return 0; -+ } -+ if (!udev->slot_id) { -+ printk(KERN_DEBUG "xHCI %s called with unaddressed device\n", -+ func); -+ return -EINVAL; -+ } -+ return 1; -+} -+ -+static int xhci_configure_endpoint(struct xhci_hcd *xhci, -+ struct usb_device *udev, struct xhci_command *command, -+ bool ctx_change, bool must_succeed); -+ -+/* -+ * Full speed devices may have a max packet size greater than 8 bytes, but the -+ * USB core doesn't know that until it reads the first 8 bytes of the -+ * descriptor. If the usb_device's max packet size changes after that point, -+ * we need to issue an evaluate context command and wait on it. -+ */ -+static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, -+ unsigned int ep_index, struct urb *urb) -+{ -+ struct xhci_container_ctx *in_ctx; -+ struct xhci_container_ctx *out_ctx; -+ struct xhci_input_control_ctx *ctrl_ctx; -+ struct xhci_ep_ctx *ep_ctx; -+ int max_packet_size; -+ int hw_max_packet_size; -+ int ret = 0; -+ -+ out_ctx = xhci->devs[slot_id]->out_ctx; -+ ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); -+ hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2); -+ max_packet_size = urb->dev->ep0.desc.wMaxPacketSize; -+ if (hw_max_packet_size != max_packet_size) { -+ xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n"); -+ xhci_dbg(xhci, "Max packet size in usb_device = %d\n", -+ max_packet_size); -+ xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n", -+ hw_max_packet_size); -+ xhci_dbg(xhci, "Issuing evaluate context command.\n"); -+ -+ /* Set up the modified control endpoint 0 */ -+ xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, -+ xhci->devs[slot_id]->out_ctx, ep_index); -+ in_ctx = xhci->devs[slot_id]->in_ctx; -+ ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); -+ ep_ctx->ep_info2 &= ~MAX_PACKET_MASK; -+ ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size); -+ -+ /* Set up the input context flags for the command */ -+ /* FIXME: This won't work if a non-default control endpoint -+ * changes max packet sizes. -+ */ -+ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); -+ ctrl_ctx->add_flags = EP0_FLAG; -+ ctrl_ctx->drop_flags = 0; -+ -+ xhci_dbg(xhci, "Slot %d input context\n", slot_id); -+ xhci_dbg_ctx(xhci, in_ctx, ep_index); -+ xhci_dbg(xhci, "Slot %d output context\n", slot_id); -+ xhci_dbg_ctx(xhci, out_ctx, ep_index); -+ -+ ret = xhci_configure_endpoint(xhci, urb->dev, NULL, -+ true, false); -+ -+ /* Clean up the input context for later use by bandwidth -+ * functions. -+ */ -+ ctrl_ctx->add_flags = SLOT_FLAG; -+ } -+ return ret; -+} -+ -+/* -+ * non-error returns are a promise to giveback() the urb later -+ * we drop ownership so next owner (or urb unlink) can get it -+ */ -+int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) -+{ -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ unsigned long flags; -+ int ret = 0; -+ unsigned int slot_id, ep_index; -+ -+ -+ if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) -+ return -EINVAL; -+ -+ slot_id = urb->dev->slot_id; -+ ep_index = xhci_get_endpoint_index(&urb->ep->desc); -+ -+ if (!xhci->devs || !xhci->devs[slot_id]) { -+ if (!in_interrupt()) -+ dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); -+ ret = -EINVAL; -+ goto exit; -+ } -+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { -+ if (!in_interrupt()) -+ xhci_dbg(xhci, "urb submitted during PCI suspend\n"); -+ ret = -ESHUTDOWN; -+ goto exit; -+ } -+ if (usb_endpoint_xfer_control(&urb->ep->desc)) { -+ /* Check to see if the max packet size for the default control -+ * endpoint changed during FS device enumeration -+ */ -+ if (urb->dev->speed == USB_SPEED_FULL) { -+ ret = xhci_check_maxpacket(xhci, slot_id, -+ ep_index, urb); -+ if (ret < 0) -+ return ret; -+ } -+ -+ /* We have a spinlock and interrupts disabled, so we must pass -+ * atomic context to this function, which may allocate memory. -+ */ -+ spin_lock_irqsave(&xhci->lock, flags); -+ if (xhci->xhc_state & XHCI_STATE_DYING) -+ goto dying; -+ ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, -+ slot_id, ep_index); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { -+ spin_lock_irqsave(&xhci->lock, flags); -+ if (xhci->xhc_state & XHCI_STATE_DYING) -+ goto dying; -+ ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, -+ slot_id, ep_index); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { -+ spin_lock_irqsave(&xhci->lock, flags); -+ if (xhci->xhc_state & XHCI_STATE_DYING) -+ goto dying; -+ ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, -+ slot_id, ep_index); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ } else { -+ ret = -EINVAL; -+ } -+exit: -+ return ret; -+dying: -+ xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " -+ "non-responsive xHCI host.\n", -+ urb->ep->desc.bEndpointAddress, urb); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ return -ESHUTDOWN; -+} -+ -+/* -+ * Remove the URB's TD from the endpoint ring. This may cause the HC to stop -+ * USB transfers, potentially stopping in the middle of a TRB buffer. The HC -+ * should pick up where it left off in the TD, unless a Set Transfer Ring -+ * Dequeue Pointer is issued. -+ * -+ * The TRBs that make up the buffers for the canceled URB will be "removed" from -+ * the ring. Since the ring is a contiguous structure, they can't be physically -+ * removed. Instead, there are two options: -+ * -+ * 1) If the HC is in the middle of processing the URB to be canceled, we -+ * simply move the ring's dequeue pointer past those TRBs using the Set -+ * Transfer Ring Dequeue Pointer command. This will be the common case, -+ * when drivers timeout on the last submitted URB and attempt to cancel. -+ * -+ * 2) If the HC is in the middle of a different TD, we turn the TRBs into a -+ * series of 1-TRB transfer no-op TDs. (No-ops shouldn't be chained.) The -+ * HC will need to invalidate the any TRBs it has cached after the stop -+ * endpoint command, as noted in the xHCI 0.95 errata. -+ * -+ * 3) The TD may have completed by the time the Stop Endpoint Command -+ * completes, so software needs to handle that case too. -+ * -+ * This function should protect against the TD enqueueing code ringing the -+ * doorbell while this code is waiting for a Stop Endpoint command to complete. -+ * It also needs to account for multiple cancellations on happening at the same -+ * time for the same endpoint. -+ * -+ * Note that this function can be called in any context, or so says -+ * usb_hcd_unlink_urb() -+ */ -+int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) -+{ -+ unsigned long flags; -+ int ret; -+ u32 temp; -+ struct xhci_hcd *xhci; -+ struct xhci_td *td; -+ unsigned int ep_index; -+ struct xhci_ring *ep_ring; -+ struct xhci_virt_ep *ep; -+ -+ xhci = hcd_to_xhci(hcd); -+ spin_lock_irqsave(&xhci->lock, flags); -+ /* Make sure the URB hasn't completed or been unlinked already */ -+ ret = usb_hcd_check_unlink_urb(hcd, urb, status); -+ if (ret || !urb->hcpriv) -+ goto done; -+ temp = xhci_readl(xhci, &xhci->op_regs->status); -+ if (temp == 0xffffffff) { -+ xhci_dbg(xhci, "HW died, freeing TD.\n"); -+ td = (struct xhci_td *) urb->hcpriv; -+ -+ usb_hcd_unlink_urb_from_ep(hcd, urb); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN); -+ kfree(td); -+ return ret; -+ } -+ if (xhci->xhc_state & XHCI_STATE_DYING) { -+ xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " -+ "non-responsive xHCI host.\n", -+ urb->ep->desc.bEndpointAddress, urb); -+ /* Let the stop endpoint command watchdog timer (which set this -+ * state) finish cleaning up the endpoint TD lists. We must -+ * have caught it in the middle of dropping a lock and giving -+ * back an URB. -+ */ -+ goto done; -+ } -+ -+ xhci_dbg(xhci, "Cancel URB %p\n", urb); -+ xhci_dbg(xhci, "Event ring:\n"); -+ xhci_debug_ring(xhci, xhci->event_ring); -+ ep_index = xhci_get_endpoint_index(&urb->ep->desc); -+ ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; -+ ep_ring = ep->ring; -+ xhci_dbg(xhci, "Endpoint ring:\n"); -+ xhci_debug_ring(xhci, ep_ring); -+ td = (struct xhci_td *) urb->hcpriv; -+ -+ list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); -+ /* Queue a stop endpoint command, but only if this is -+ * the first cancellation to be handled. -+ */ -+ if (!(ep->ep_state & EP_HALT_PENDING)) { -+ ep->ep_state |= EP_HALT_PENDING; -+ ep->stop_cmds_pending++; -+ ep->stop_cmd_timer.expires = jiffies + -+ XHCI_STOP_EP_CMD_TIMEOUT * HZ; -+ add_timer(&ep->stop_cmd_timer); -+ xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index); -+ xhci_ring_cmd_db(xhci); -+ } -+done: -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ return ret; -+} -+ -+/* Drop an endpoint from a new bandwidth configuration for this device. -+ * Only one call to this function is allowed per endpoint before -+ * check_bandwidth() or reset_bandwidth() must be called. -+ * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will -+ * add the endpoint to the schedule with possibly new parameters denoted by a -+ * different endpoint descriptor in usb_host_endpoint. -+ * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is -+ * not allowed. -+ * -+ * The USB core will not allow URBs to be queued to an endpoint that is being -+ * disabled, so there's no need for mutual exclusion to protect -+ * the xhci->devs[slot_id] structure. -+ */ -+int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, -+ struct usb_host_endpoint *ep) -+{ -+ struct xhci_hcd *xhci; -+ struct xhci_container_ctx *in_ctx, *out_ctx; -+ struct xhci_input_control_ctx *ctrl_ctx; -+ struct xhci_slot_ctx *slot_ctx; -+ unsigned int last_ctx; -+ unsigned int ep_index; -+ struct xhci_ep_ctx *ep_ctx; -+ u32 drop_flag; -+ u32 new_add_flags, new_drop_flags, new_slot_info; -+ int ret; -+ -+ ret = xhci_check_args(hcd, udev, ep, 1, __func__); -+ if (ret <= 0) -+ return ret; -+ xhci = hcd_to_xhci(hcd); -+ xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); -+ -+ drop_flag = xhci_get_endpoint_flag(&ep->desc); -+ if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { -+ xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", -+ __func__, drop_flag); -+ return 0; -+ } -+ -+ if (!xhci->devs || !xhci->devs[udev->slot_id]) { -+ xhci_warn(xhci, "xHCI %s called with unaddressed device\n", -+ __func__); -+ return -EINVAL; -+ } -+ -+ in_ctx = xhci->devs[udev->slot_id]->in_ctx; -+ out_ctx = xhci->devs[udev->slot_id]->out_ctx; -+ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); -+ ep_index = xhci_get_endpoint_index(&ep->desc); -+ ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); -+ /* If the HC already knows the endpoint is disabled, -+ * or the HCD has noted it is disabled, ignore this request -+ */ -+ if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED || -+ ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) { -+ xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", -+ __func__, ep); -+ return 0; -+ } -+ -+ ctrl_ctx->drop_flags |= drop_flag; -+ new_drop_flags = ctrl_ctx->drop_flags; -+ -+ ctrl_ctx->add_flags &= ~drop_flag; -+ new_add_flags = ctrl_ctx->add_flags; -+ -+ last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags); -+ slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); -+ /* Update the last valid endpoint context, if we deleted the last one */ -+ if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) { -+ slot_ctx->dev_info &= ~LAST_CTX_MASK; -+ slot_ctx->dev_info |= LAST_CTX(last_ctx); -+ } -+ new_slot_info = slot_ctx->dev_info; -+ -+ xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); -+ -+ xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", -+ (unsigned int) ep->desc.bEndpointAddress, -+ udev->slot_id, -+ (unsigned int) new_drop_flags, -+ (unsigned int) new_add_flags, -+ (unsigned int) new_slot_info); -+ return 0; -+} -+ -+/* Add an endpoint to a new possible bandwidth configuration for this device. -+ * Only one call to this function is allowed per endpoint before -+ * check_bandwidth() or reset_bandwidth() must be called. -+ * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will -+ * add the endpoint to the schedule with possibly new parameters denoted by a -+ * different endpoint descriptor in usb_host_endpoint. -+ * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is -+ * not allowed. -+ * -+ * The USB core will not allow URBs to be queued to an endpoint until the -+ * configuration or alt setting is installed in the device, so there's no need -+ * for mutual exclusion to protect the xhci->devs[slot_id] structure. -+ */ -+int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, -+ struct usb_host_endpoint *ep) -+{ -+ struct xhci_hcd *xhci; -+ struct xhci_container_ctx *in_ctx, *out_ctx; -+ unsigned int ep_index; -+ struct xhci_ep_ctx *ep_ctx; -+ struct xhci_slot_ctx *slot_ctx; -+ struct xhci_input_control_ctx *ctrl_ctx; -+ u32 added_ctxs; -+ unsigned int last_ctx; -+ u32 new_add_flags, new_drop_flags, new_slot_info; -+ int ret = 0; -+ -+ ret = xhci_check_args(hcd, udev, ep, 1, __func__); -+ if (ret <= 0) { -+ /* So we won't queue a reset ep command for a root hub */ -+ ep->hcpriv = NULL; -+ return ret; -+ } -+ xhci = hcd_to_xhci(hcd); -+ -+ added_ctxs = xhci_get_endpoint_flag(&ep->desc); -+ last_ctx = xhci_last_valid_endpoint(added_ctxs); -+ if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) { -+ /* FIXME when we have to issue an evaluate endpoint command to -+ * deal with ep0 max packet size changing once we get the -+ * descriptors -+ */ -+ xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n", -+ __func__, added_ctxs); -+ return 0; -+ } -+ -+ if (!xhci->devs || !xhci->devs[udev->slot_id]) { -+ xhci_warn(xhci, "xHCI %s called with unaddressed device\n", -+ __func__); -+ return -EINVAL; -+ } -+ -+ in_ctx = xhci->devs[udev->slot_id]->in_ctx; -+ out_ctx = xhci->devs[udev->slot_id]->out_ctx; -+ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); -+ ep_index = xhci_get_endpoint_index(&ep->desc); -+ ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); -+ /* If the HCD has already noted the endpoint is enabled, -+ * ignore this request. -+ */ -+ if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) { -+ xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", -+ __func__, ep); -+ return 0; -+ } -+ -+ /* -+ * Configuration and alternate setting changes must be done in -+ * process context, not interrupt context (or so documenation -+ * for usb_set_interface() and usb_set_configuration() claim). -+ */ -+ if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], -+ udev, ep, GFP_NOIO) < 0) { -+ dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", -+ __func__, ep->desc.bEndpointAddress); -+ return -ENOMEM; -+ } -+ -+ ctrl_ctx->add_flags |= added_ctxs; -+ new_add_flags = ctrl_ctx->add_flags; -+ -+ /* If xhci_endpoint_disable() was called for this endpoint, but the -+ * xHC hasn't been notified yet through the check_bandwidth() call, -+ * this re-adds a new state for the endpoint from the new endpoint -+ * descriptors. We must drop and re-add this endpoint, so we leave the -+ * drop flags alone. -+ */ -+ new_drop_flags = ctrl_ctx->drop_flags; -+ -+ slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); -+ /* Update the last valid endpoint context, if we just added one past */ -+ if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) { -+ slot_ctx->dev_info &= ~LAST_CTX_MASK; -+ slot_ctx->dev_info |= LAST_CTX(last_ctx); -+ } -+ new_slot_info = slot_ctx->dev_info; -+ -+ /* Store the usb_device pointer for later use */ -+ ep->hcpriv = udev; -+ -+ xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", -+ (unsigned int) ep->desc.bEndpointAddress, -+ udev->slot_id, -+ (unsigned int) new_drop_flags, -+ (unsigned int) new_add_flags, -+ (unsigned int) new_slot_info); -+ return 0; -+} -+ -+static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev) -+{ -+ struct xhci_input_control_ctx *ctrl_ctx; -+ struct xhci_ep_ctx *ep_ctx; -+ struct xhci_slot_ctx *slot_ctx; -+ int i; -+ -+ /* When a device's add flag and drop flag are zero, any subsequent -+ * configure endpoint command will leave that endpoint's state -+ * untouched. Make sure we don't leave any old state in the input -+ * endpoint contexts. -+ */ -+ ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); -+ ctrl_ctx->drop_flags = 0; -+ ctrl_ctx->add_flags = 0; -+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); -+ slot_ctx->dev_info &= ~LAST_CTX_MASK; -+ /* Endpoint 0 is always valid */ -+ slot_ctx->dev_info |= LAST_CTX(1); -+ for (i = 1; i < 31; ++i) { -+ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i); -+ ep_ctx->ep_info = 0; -+ ep_ctx->ep_info2 = 0; -+ ep_ctx->deq = 0; -+ ep_ctx->tx_info = 0; -+ } -+} -+ -+static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, -+ struct usb_device *udev, int *cmd_status) -+{ -+ int ret; -+ -+ switch (*cmd_status) { -+ case COMP_ENOMEM: -+ dev_warn(&udev->dev, "Not enough host controller resources " -+ "for new device state.\n"); -+ ret = -ENOMEM; -+ /* FIXME: can we allocate more resources for the HC? */ -+ break; -+ case COMP_BW_ERR: -+ dev_warn(&udev->dev, "Not enough bandwidth " -+ "for new device state.\n"); -+ ret = -ENOSPC; -+ /* FIXME: can we go back to the old state? */ -+ break; -+ case COMP_TRB_ERR: -+ /* the HCD set up something wrong */ -+ dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, " -+ "add flag = 1, " -+ "and endpoint is not disabled.\n"); -+ ret = -EINVAL; -+ break; -+ case COMP_SUCCESS: -+ dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); -+ ret = 0; -+ break; -+ default: -+ xhci_err(xhci, "ERROR: unexpected command completion " -+ "code 0x%x.\n", *cmd_status); -+ ret = -EINVAL; -+ break; -+ } -+ return ret; -+} -+ -+static int xhci_evaluate_context_result(struct xhci_hcd *xhci, -+ struct usb_device *udev, int *cmd_status) -+{ -+ int ret; -+ struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; -+ -+ switch (*cmd_status) { -+ case COMP_EINVAL: -+ dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate " -+ "context command.\n"); -+ ret = -EINVAL; -+ break; -+ case COMP_EBADSLT: -+ dev_warn(&udev->dev, "WARN: slot not enabled for" -+ "evaluate context command.\n"); -+ case COMP_CTX_STATE: -+ dev_warn(&udev->dev, "WARN: invalid context state for " -+ "evaluate context command.\n"); -+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); -+ ret = -EINVAL; -+ break; -+ case COMP_SUCCESS: -+ dev_dbg(&udev->dev, "Successful evaluate context command\n"); -+ ret = 0; -+ break; -+ default: -+ xhci_err(xhci, "ERROR: unexpected command completion " -+ "code 0x%x.\n", *cmd_status); -+ ret = -EINVAL; -+ break; -+ } -+ return ret; -+} -+ -+/* Issue a configure endpoint command or evaluate context command -+ * and wait for it to finish. -+ */ -+static int xhci_configure_endpoint(struct xhci_hcd *xhci, -+ struct usb_device *udev, -+ struct xhci_command *command, -+ bool ctx_change, bool must_succeed) -+{ -+ int ret; -+ int timeleft; -+ unsigned long flags; -+ struct xhci_container_ctx *in_ctx; -+ struct completion *cmd_completion; -+ int *cmd_status; -+ struct xhci_virt_device *virt_dev; -+ -+ spin_lock_irqsave(&xhci->lock, flags); -+ virt_dev = xhci->devs[udev->slot_id]; -+ if (command) { -+ in_ctx = command->in_ctx; -+ cmd_completion = command->completion; -+ cmd_status = &command->status; -+ command->command_trb = xhci->cmd_ring->enqueue; -+ list_add_tail(&command->cmd_list, &virt_dev->cmd_list); -+ } else { -+ in_ctx = virt_dev->in_ctx; -+ cmd_completion = &virt_dev->cmd_completion; -+ cmd_status = &virt_dev->cmd_status; -+ } -+ -+ if (!ctx_change) -+ ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, -+ udev->slot_id, must_succeed); -+ else -+ ret = xhci_queue_evaluate_context(xhci, in_ctx->dma, -+ udev->slot_id); -+ if (ret < 0) { -+ if (command) -+ list_del(&command->cmd_list); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); -+ return -ENOMEM; -+ } -+ xhci_ring_cmd_db(xhci); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ -+ /* Wait for the configure endpoint command to complete */ -+ timeleft = wait_for_completion_interruptible_timeout( -+ cmd_completion, -+ USB_CTRL_SET_TIMEOUT); -+ if (timeleft <= 0) { -+ xhci_warn(xhci, "%s while waiting for %s command\n", -+ timeleft == 0 ? "Timeout" : "Signal", -+ ctx_change == 0 ? -+ "configure endpoint" : -+ "evaluate context"); -+ /* FIXME cancel the configure endpoint command */ -+ return -ETIME; -+ } -+ -+ if (!ctx_change) -+ return xhci_configure_endpoint_result(xhci, udev, cmd_status); -+ return xhci_evaluate_context_result(xhci, udev, cmd_status); -+} -+ -+/* Called after one or more calls to xhci_add_endpoint() or -+ * xhci_drop_endpoint(). If this call fails, the USB core is expected -+ * to call xhci_reset_bandwidth(). -+ * -+ * Since we are in the middle of changing either configuration or -+ * installing a new alt setting, the USB core won't allow URBs to be -+ * enqueued for any endpoint on the old config or interface. Nothing -+ * else should be touching the xhci->devs[slot_id] structure, so we -+ * don't need to take the xhci->lock for manipulating that. -+ */ -+int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) -+{ -+ int i; -+ int ret = 0; -+ struct xhci_hcd *xhci; -+ struct xhci_virt_device *virt_dev; -+ struct xhci_input_control_ctx *ctrl_ctx; -+ struct xhci_slot_ctx *slot_ctx; -+ -+ ret = xhci_check_args(hcd, udev, NULL, 0, __func__); -+ if (ret <= 0) -+ return ret; -+ xhci = hcd_to_xhci(hcd); -+ -+ if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) { -+ xhci_warn(xhci, "xHCI %s called with unaddressed device\n", -+ __func__); -+ return -EINVAL; -+ } -+ xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); -+ virt_dev = xhci->devs[udev->slot_id]; -+ -+ /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ -+ ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); -+ ctrl_ctx->add_flags |= SLOT_FLAG; -+ ctrl_ctx->add_flags &= ~EP0_FLAG; -+ ctrl_ctx->drop_flags &= ~SLOT_FLAG; -+ ctrl_ctx->drop_flags &= ~EP0_FLAG; -+ xhci_dbg(xhci, "New Input Control Context:\n"); -+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); -+ xhci_dbg_ctx(xhci, virt_dev->in_ctx, -+ LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); -+ -+ ret = xhci_configure_endpoint(xhci, udev, NULL, -+ false, false); -+ if (ret) { -+ /* Callee should call reset_bandwidth() */ -+ return ret; -+ } -+ -+ xhci_dbg(xhci, "Output context after successful config ep cmd:\n"); -+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, -+ LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); -+ -+ xhci_zero_in_ctx(xhci, virt_dev); -+ /* Install new rings and free or cache any old rings */ -+ for (i = 1; i < 31; ++i) { -+ if (!virt_dev->eps[i].new_ring) -+ continue; -+ /* Only cache or free the old ring if it exists. -+ * It may not if this is the first add of an endpoint. -+ */ -+ if (virt_dev->eps[i].ring) { -+ xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); -+ } -+ virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; -+ virt_dev->eps[i].new_ring = NULL; -+ } -+ -+ return ret; -+} -+ -+void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) -+{ -+ struct xhci_hcd *xhci; -+ struct xhci_virt_device *virt_dev; -+ int i, ret; -+ -+ ret = xhci_check_args(hcd, udev, NULL, 0, __func__); -+ if (ret <= 0) -+ return; -+ xhci = hcd_to_xhci(hcd); -+ -+ if (!xhci->devs || !xhci->devs[udev->slot_id]) { -+ xhci_warn(xhci, "xHCI %s called with unaddressed device\n", -+ __func__); -+ return; -+ } -+ xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); -+ virt_dev = xhci->devs[udev->slot_id]; -+ /* Free any rings allocated for added endpoints */ -+ for (i = 0; i < 31; ++i) { -+ if (virt_dev->eps[i].new_ring) { -+ xhci_ring_free(xhci, virt_dev->eps[i].new_ring); -+ virt_dev->eps[i].new_ring = NULL; -+ } -+ } -+ xhci_zero_in_ctx(xhci, virt_dev); -+} -+ -+static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci, -+ struct xhci_container_ctx *in_ctx, -+ struct xhci_container_ctx *out_ctx, -+ u32 add_flags, u32 drop_flags) -+{ -+ struct xhci_input_control_ctx *ctrl_ctx; -+ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); -+ ctrl_ctx->add_flags = add_flags; -+ ctrl_ctx->drop_flags = drop_flags; -+ xhci_slot_copy(xhci, in_ctx, out_ctx); -+ ctrl_ctx->add_flags |= SLOT_FLAG; -+ -+ xhci_dbg(xhci, "Input Context:\n"); -+ xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags)); -+} -+ -+void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, -+ unsigned int slot_id, unsigned int ep_index, -+ struct xhci_dequeue_state *deq_state) -+{ -+ struct xhci_container_ctx *in_ctx; -+ struct xhci_ep_ctx *ep_ctx; -+ u32 added_ctxs; -+ dma_addr_t addr; -+ -+ xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, -+ xhci->devs[slot_id]->out_ctx, ep_index); -+ in_ctx = xhci->devs[slot_id]->in_ctx; -+ ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); -+ addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg, -+ deq_state->new_deq_ptr); -+ if (addr == 0) { -+ xhci_warn(xhci, "WARN Cannot submit config ep after " -+ "reset ep command\n"); -+ xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n", -+ deq_state->new_deq_seg, -+ deq_state->new_deq_ptr); -+ return; -+ } -+ ep_ctx->deq = addr | deq_state->new_cycle_state; -+ -+ added_ctxs = xhci_get_endpoint_flag_from_index(ep_index); -+ xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx, -+ xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs); -+} -+ -+void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, -+ struct usb_device *udev, unsigned int ep_index) -+{ -+ struct xhci_dequeue_state deq_state; -+ struct xhci_virt_ep *ep; -+ -+ xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n"); -+ ep = &xhci->devs[udev->slot_id]->eps[ep_index]; -+ /* We need to move the HW's dequeue pointer past this TD, -+ * or it will attempt to resend it on the next doorbell ring. -+ */ -+ xhci_find_new_dequeue_state(xhci, udev->slot_id, -+ ep_index, ep->stopped_td, -+ &deq_state); -+ -+ /* HW with the reset endpoint quirk will use the saved dequeue state to -+ * issue a configure endpoint command later. -+ */ -+ if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) { -+ xhci_dbg(xhci, "Queueing new dequeue state\n"); -+ xhci_queue_new_dequeue_state(xhci, udev->slot_id, -+ ep_index, &deq_state); -+ } else { -+ /* Better hope no one uses the input context between now and the -+ * reset endpoint completion! -+ */ -+ xhci_dbg(xhci, "Setting up input context for " -+ "configure endpoint command\n"); -+ xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id, -+ ep_index, &deq_state); -+ } -+} -+ -+/* Deal with stalled endpoints. The core should have sent the control message -+ * to clear the halt condition. However, we need to make the xHCI hardware -+ * reset its sequence number, since a device will expect a sequence number of -+ * zero after the halt condition is cleared. -+ * Context: in_interrupt -+ */ -+void xhci_endpoint_reset(struct usb_hcd *hcd, -+ struct usb_host_endpoint *ep) -+{ -+ struct xhci_hcd *xhci; -+ struct usb_device *udev; -+ unsigned int ep_index; -+ unsigned long flags; -+ int ret; -+ struct xhci_virt_ep *virt_ep; -+ -+ xhci = hcd_to_xhci(hcd); -+ udev = (struct usb_device *) ep->hcpriv; -+ /* Called with a root hub endpoint (or an endpoint that wasn't added -+ * with xhci_add_endpoint() -+ */ -+ if (!ep->hcpriv) -+ return; -+ ep_index = xhci_get_endpoint_index(&ep->desc); -+ virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index]; -+ if (!virt_ep->stopped_td) { -+ xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n", -+ ep->desc.bEndpointAddress); -+ return; -+ } -+ if (usb_endpoint_xfer_control(&ep->desc)) { -+ xhci_dbg(xhci, "Control endpoint stall already handled.\n"); -+ return; -+ } -+ -+ xhci_dbg(xhci, "Queueing reset endpoint command\n"); -+ spin_lock_irqsave(&xhci->lock, flags); -+ ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index); -+ /* -+ * Can't change the ring dequeue pointer until it's transitioned to the -+ * stopped state, which is only upon a successful reset endpoint -+ * command. Better hope that last command worked! -+ */ -+ if (!ret) { -+ xhci_cleanup_stalled_ring(xhci, udev, ep_index); -+ kfree(virt_ep->stopped_td); -+ xhci_ring_cmd_db(xhci); -+ } -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ -+ if (ret) -+ xhci_warn(xhci, "FIXME allocate a new ring segment\n"); -+} -+ -+/* -+ * This submits a Reset Device Command, which will set the device state to 0, -+ * set the device address to 0, and disable all the endpoints except the default -+ * control endpoint. The USB core should come back and call -+ * xhci_address_device(), and then re-set up the configuration. If this is -+ * called because of a usb_reset_and_verify_device(), then the old alternate -+ * settings will be re-installed through the normal bandwidth allocation -+ * functions. -+ * -+ * Wait for the Reset Device command to finish. Remove all structures -+ * associated with the endpoints that were disabled. Clear the input device -+ * structure? Cache the rings? Reset the control endpoint 0 max packet size? -+ */ -+int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev) -+{ -+ int ret, i; -+ unsigned long flags; -+ struct xhci_hcd *xhci; -+ unsigned int slot_id; -+ struct xhci_virt_device *virt_dev; -+ struct xhci_command *reset_device_cmd; -+ int timeleft; -+ int last_freed_endpoint; -+ -+ ret = xhci_check_args(hcd, udev, NULL, 0, __func__); -+ if (ret <= 0) -+ return ret; -+ xhci = hcd_to_xhci(hcd); -+ slot_id = udev->slot_id; -+ virt_dev = xhci->devs[slot_id]; -+ if (!virt_dev) { -+ xhci_dbg(xhci, "%s called with invalid slot ID %u\n", -+ __func__, slot_id); -+ return -EINVAL; -+ } -+ -+ xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); -+ /* Allocate the command structure that holds the struct completion. -+ * Assume we're in process context, since the normal device reset -+ * process has to wait for the device anyway. Storage devices are -+ * reset as part of error handling, so use GFP_NOIO instead of -+ * GFP_KERNEL. -+ */ -+ reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); -+ if (!reset_device_cmd) { -+ xhci_dbg(xhci, "Couldn't allocate command structure.\n"); -+ return -ENOMEM; -+ } -+ -+ /* Attempt to submit the Reset Device command to the command ring */ -+ spin_lock_irqsave(&xhci->lock, flags); -+ reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; -+ list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); -+ ret = xhci_queue_reset_device(xhci, slot_id); -+ if (ret) { -+ xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); -+ list_del(&reset_device_cmd->cmd_list); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ goto command_cleanup; -+ } -+ xhci_ring_cmd_db(xhci); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ -+ /* Wait for the Reset Device command to finish */ -+ timeleft = wait_for_completion_interruptible_timeout( -+ reset_device_cmd->completion, -+ USB_CTRL_SET_TIMEOUT); -+ if (timeleft <= 0) { -+ xhci_warn(xhci, "%s while waiting for reset device command\n", -+ timeleft == 0 ? "Timeout" : "Signal"); -+ spin_lock_irqsave(&xhci->lock, flags); -+ /* The timeout might have raced with the event ring handler, so -+ * only delete from the list if the item isn't poisoned. -+ */ -+ if (reset_device_cmd->cmd_list.next != LIST_POISON1) -+ list_del(&reset_device_cmd->cmd_list); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ ret = -ETIME; -+ goto command_cleanup; -+ } -+ -+ /* The Reset Device command can't fail, according to the 0.95/0.96 spec, -+ * unless we tried to reset a slot ID that wasn't enabled, -+ * or the device wasn't in the addressed or configured state. -+ */ -+ ret = reset_device_cmd->status; -+ switch (ret) { -+ case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */ -+ case COMP_CTX_STATE: /* 0.96 completion code for same thing */ -+ xhci_info(xhci, "Can't reset device (slot ID %u) in %s state\n", -+ slot_id, -+ xhci_get_slot_state(xhci, virt_dev->out_ctx)); -+ xhci_info(xhci, "Not freeing device rings.\n"); -+ /* Don't treat this as an error. May change my mind later. */ -+ ret = 0; -+ goto command_cleanup; -+ case COMP_SUCCESS: -+ xhci_dbg(xhci, "Successful reset device command.\n"); -+ break; -+ default: -+ if (xhci_is_vendor_info_code(xhci, ret)) -+ break; -+ xhci_warn(xhci, "Unknown completion code %u for " -+ "reset device command.\n", ret); -+ ret = -EINVAL; -+ goto command_cleanup; -+ } -+ -+ /* Everything but endpoint 0 is disabled, so free or cache the rings. */ -+ last_freed_endpoint = 1; -+ for (i = 1; i < 31; ++i) { -+ if (!virt_dev->eps[i].ring) -+ continue; -+ xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); -+ last_freed_endpoint = i; -+ } -+ xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); -+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); -+ ret = 0; -+ -+command_cleanup: -+ xhci_free_command(xhci, reset_device_cmd); -+ return ret; -+} -+ -+/* -+ * At this point, the struct usb_device is about to go away, the device has -+ * disconnected, and all traffic has been stopped and the endpoints have been -+ * disabled. Free any HC data structures associated with that device. -+ */ -+void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) -+{ -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ struct xhci_virt_device *virt_dev; -+ unsigned long flags; -+ u32 state; -+ int i; -+ -+ if (udev->slot_id == 0) -+ return; -+ virt_dev = xhci->devs[udev->slot_id]; -+ if (!virt_dev) -+ return; -+ -+ /* Stop any wayward timer functions (which may grab the lock) */ -+ for (i = 0; i < 31; ++i) { -+ virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING; -+ del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); -+ } -+ -+ spin_lock_irqsave(&xhci->lock, flags); -+ /* Don't disable the slot if the host controller is dead. */ -+ state = xhci_readl(xhci, &xhci->op_regs->status); -+ if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { -+ xhci_free_virt_device(xhci, udev->slot_id); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ return; -+ } -+ -+ if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) { -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); -+ return; -+ } -+ xhci_ring_cmd_db(xhci); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ /* -+ * Event command completion handler will free any data structures -+ * associated with the slot. XXX Can free sleep? -+ */ -+} -+ -+/* -+ * Returns 0 if the xHC ran out of device slots, the Enable Slot command -+ * timed out, or allocating memory failed. Returns 1 on success. -+ */ -+int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) -+{ -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ unsigned long flags; -+ int timeleft; -+ int ret; -+ -+ spin_lock_irqsave(&xhci->lock, flags); -+ ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); -+ if (ret) { -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); -+ return 0; -+ } -+ xhci_ring_cmd_db(xhci); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ -+ /* XXX: how much time for xHC slot assignment? */ -+ timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, -+ USB_CTRL_SET_TIMEOUT); -+ if (timeleft <= 0) { -+ xhci_warn(xhci, "%s while waiting for a slot\n", -+ timeleft == 0 ? "Timeout" : "Signal"); -+ /* FIXME cancel the enable slot request */ -+ return 0; -+ } -+ -+ if (!xhci->slot_id) { -+ xhci_err(xhci, "Error while assigning device slot ID\n"); -+ return 0; -+ } -+ /* xhci_alloc_virt_device() does not touch rings; no need to lock */ -+ if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) { -+ /* Disable slot, if we can do it without mem alloc */ -+ xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); -+ spin_lock_irqsave(&xhci->lock, flags); -+ if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) -+ xhci_ring_cmd_db(xhci); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ return 0; -+ } -+ udev->slot_id = xhci->slot_id; -+ /* Is this a LS or FS device under a HS hub? */ -+ /* Hub or peripherial? */ -+ return 1; -+} -+ -+/* -+ * Issue an Address Device command (which will issue a SetAddress request to -+ * the device). -+ * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so -+ * we should only issue and wait on one address command at the same time. -+ * -+ * We add one to the device address issued by the hardware because the USB core -+ * uses address 1 for the root hubs (even though they're not really devices). -+ */ -+int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) -+{ -+ unsigned long flags; -+ int timeleft; -+ struct xhci_virt_device *virt_dev; -+ int ret = 0; -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ struct xhci_slot_ctx *slot_ctx; -+ struct xhci_input_control_ctx *ctrl_ctx; -+ u64 temp_64; -+ -+ if (!udev->slot_id) { -+ xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); -+ return -EINVAL; -+ } -+ -+ virt_dev = xhci->devs[udev->slot_id]; -+ -+ /* If this is a Set Address to an unconfigured device, setup ep 0 */ -+ if (!udev->config) -+ xhci_setup_addressable_virt_dev(xhci, udev); -+ /* Otherwise, assume the core has the device configured how it wants */ -+ xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); -+ xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); -+ -+ spin_lock_irqsave(&xhci->lock, flags); -+ ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, -+ udev->slot_id); -+ if (ret) { -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); -+ return ret; -+ } -+ xhci_ring_cmd_db(xhci); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ -+ /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ -+ timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, -+ USB_CTRL_SET_TIMEOUT); -+ /* FIXME: From section 4.3.4: "Software shall be responsible for timing -+ * the SetAddress() "recovery interval" required by USB and aborting the -+ * command on a timeout. -+ */ -+ if (timeleft <= 0) { -+ xhci_warn(xhci, "%s while waiting for a slot\n", -+ timeleft == 0 ? "Timeout" : "Signal"); -+ /* FIXME cancel the address device command */ -+ return -ETIME; -+ } -+ -+ switch (virt_dev->cmd_status) { -+ case COMP_CTX_STATE: -+ case COMP_EBADSLT: -+ xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n", -+ udev->slot_id); -+ ret = -EINVAL; -+ break; -+ case COMP_TX_ERR: -+ dev_warn(&udev->dev, "Device not responding to set address.\n"); -+ ret = -EPROTO; -+ break; -+ case COMP_SUCCESS: -+ xhci_dbg(xhci, "Successful Address Device command\n"); -+ break; -+ default: -+ xhci_err(xhci, "ERROR: unexpected command completion " -+ "code 0x%x.\n", virt_dev->cmd_status); -+ xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); -+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); -+ ret = -EINVAL; -+ break; -+ } -+ if (ret) { -+ return ret; -+ } -+ temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); -+ xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64); -+ xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n", -+ udev->slot_id, -+ &xhci->dcbaa->dev_context_ptrs[udev->slot_id], -+ (unsigned long long) -+ xhci->dcbaa->dev_context_ptrs[udev->slot_id]); -+ xhci_dbg(xhci, "Output Context DMA address = %#08llx\n", -+ (unsigned long long)virt_dev->out_ctx->dma); -+ xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); -+ xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); -+ xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); -+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); -+ /* -+ * USB core uses address 1 for the roothubs, so we add one to the -+ * address given back to us by the HC. -+ */ -+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); -+ udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; -+ /* Zero the input context control for later use */ -+ ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); -+ ctrl_ctx->add_flags = 0; -+ ctrl_ctx->drop_flags = 0; -+ -+ xhci_dbg(xhci, "Device address = %d\n", udev->devnum); -+ /* XXX Meh, not sure if anyone else but choose_address uses this. */ -+ set_bit(udev->devnum, udev->bus->devmap.devicemap); -+ -+ return 0; -+} -+ -+/* Once a hub descriptor is fetched for a device, we need to update the xHC's -+ * internal data structures for the device. -+ */ -+int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, -+ struct usb_tt *tt, gfp_t mem_flags) -+{ -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ struct xhci_virt_device *vdev; -+ struct xhci_command *config_cmd; -+ struct xhci_input_control_ctx *ctrl_ctx; -+ struct xhci_slot_ctx *slot_ctx; -+ unsigned long flags; -+ unsigned think_time; -+ int ret; -+ -+ /* Ignore root hubs */ -+ if (!hdev->parent) -+ return 0; -+ -+ vdev = xhci->devs[hdev->slot_id]; -+ if (!vdev) { -+ xhci_warn(xhci, "Cannot update hub desc for unknown device.\n"); -+ return -EINVAL; -+ } -+ config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); -+ if (!config_cmd) { -+ xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); -+ return -ENOMEM; -+ } -+ -+ spin_lock_irqsave(&xhci->lock, flags); -+ xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx); -+ ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); -+ ctrl_ctx->add_flags |= SLOT_FLAG; -+ slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx); -+ slot_ctx->dev_info |= DEV_HUB; -+ if (tt->multi) -+ slot_ctx->dev_info |= DEV_MTT; -+ if (xhci->hci_version > 0x95) { -+ xhci_dbg(xhci, "xHCI version %x needs hub " -+ "TT think time and number of ports\n", -+ (unsigned int) xhci->hci_version); -+ slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild); -+ /* Set TT think time - convert from ns to FS bit times. -+ * 0 = 8 FS bit times, 1 = 16 FS bit times, -+ * 2 = 24 FS bit times, 3 = 32 FS bit times. -+ */ -+ think_time = tt->think_time; -+ if (think_time != 0) -+ think_time = (think_time / 666) - 1; -+ slot_ctx->tt_info |= TT_THINK_TIME(think_time); -+ } else { -+ xhci_dbg(xhci, "xHCI version %x doesn't need hub " -+ "TT think time or number of ports\n", -+ (unsigned int) xhci->hci_version); -+ } -+ slot_ctx->dev_state = 0; -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ -+ xhci_dbg(xhci, "Set up %s for hub device.\n", -+ (xhci->hci_version > 0x95) ? -+ "configure endpoint" : "evaluate context"); -+ xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id); -+ xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0); -+ -+ /* Issue and wait for the configure endpoint or -+ * evaluate context command. -+ */ -+ if (xhci->hci_version > 0x95) -+ ret = xhci_configure_endpoint(xhci, hdev, config_cmd, -+ false, false); -+ else -+ ret = xhci_configure_endpoint(xhci, hdev, config_cmd, -+ true, false); -+ -+ xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id); -+ xhci_dbg_ctx(xhci, vdev->out_ctx, 0); -+ -+ xhci_free_command(xhci, config_cmd); -+ return ret; -+} -+ -+int xhci_get_frame(struct usb_hcd *hcd) -+{ -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ /* EHCI mods by the periodic size. Why? */ -+ return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3; -+} -+ -+MODULE_DESCRIPTION(DRIVER_DESC); -+MODULE_AUTHOR(DRIVER_AUTHOR); -+MODULE_LICENSE("GPL"); -+ -+static int __init xhci_hcd_init(void) -+{ -+#ifdef CONFIG_PCI -+ int retval = 0; -+ -+ retval = xhci_register_pci(); -+ -+ if (retval < 0) { -+ printk(KERN_DEBUG "Problem registering PCI driver."); -+ return retval; -+ } -+#endif -+ /* -+ * Check the compiler generated sizes of structures that must be laid -+ * out in specific ways for hardware access. -+ */ -+ BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); -+ BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8); -+ BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8); -+ /* xhci_device_control has eight fields, and also -+ * embeds one xhci_slot_ctx and 31 xhci_ep_ctx -+ */ -+ BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); -+ BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); -+ BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); -+ BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8); -+ BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); -+ /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ -+ BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); -+ BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); -+ return 0; -+} -+module_init(xhci_hcd_init); -+ -+static void __exit xhci_hcd_cleanup(void) -+{ -+#ifdef CONFIG_PCI -+ xhci_unregister_pci(); -+#endif -+} -+module_exit(xhci_hcd_cleanup); |
