mm-prevent-concurrent-unmap_mapping_range-on-the-same-inode.patch
staging-brcm80211-remove-assert-to-avoid-panic-since-2.6.37-kernel.patch
staging-brcm80211-bugfix-for-softmac-crash-on-multi-cpu-configurations.patch
+staging-usbip-vhci-update-reference-count-for-usb_device.patch
+staging-usbip-vhci-give-back-urbs-from-in-flight-unlink-requests.patch
+staging-usbip-vhci-refuse-to-enqueue-for-dead-connections.patch
+staging-usbip-vhci-use-urb-dev-portnum-to-find-port.patch
--- /dev/null
+From b92a5e23737172c52656a090977408a80d7f06d1 Mon Sep 17 00:00:00 2001
+From: Max Vozeler <max@vozeler.com>
+Date: Wed, 12 Jan 2011 15:02:01 +0200
+Subject: staging: usbip: vhci: give back URBs from in-flight unlink requests
+
+From: Max Vozeler <max@vozeler.com>
+
+commit b92a5e23737172c52656a090977408a80d7f06d1 upstream.
+
+If we never received a RET_UNLINK because the TCP
+connection broke the pending URBs still need to be
+unlinked and given back.
+
+Previously processes would be stuck trying to kill
+the URB even after the device was detached.
+
+Signed-off-by: Max Vozeler <max@vozeler.com>
+Tested-by: Mark Wehby <MWehby@luxotticaRetail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/usbip/vhci.h | 3 +++
+ drivers/staging/usbip/vhci_hcd.c | 24 +++++++++++++++++++++++-
+ drivers/staging/usbip/vhci_rx.c | 15 +++++++++------
+ 3 files changed, 35 insertions(+), 7 deletions(-)
+
+--- a/drivers/staging/usbip/vhci.h
++++ b/drivers/staging/usbip/vhci.h
+@@ -119,6 +119,9 @@ void rh_port_disconnect(int rhport);
+ void vhci_rx_loop(struct usbip_task *ut);
+ void vhci_tx_loop(struct usbip_task *ut);
+
++struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
++ __u32 seqnum);
++
+ #define hardware (&the_controller->pdev.dev)
+
+ static inline struct vhci_device *port_to_vdev(__u32 port)
+--- a/drivers/staging/usbip/vhci_hcd.c
++++ b/drivers/staging/usbip/vhci_hcd.c
+@@ -808,7 +808,6 @@ static int vhci_urb_dequeue(struct usb_h
+ return 0;
+ }
+
+-
+ static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
+ {
+ struct vhci_unlink *unlink, *tmp;
+@@ -816,11 +815,34 @@ static void vhci_device_unlink_cleanup(s
+ spin_lock(&vdev->priv_lock);
+
+ list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
++ usbip_uinfo("unlink cleanup tx %lu\n", unlink->unlink_seqnum);
+ list_del(&unlink->list);
+ kfree(unlink);
+ }
+
+ list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
++ struct urb *urb;
++
++ /* give back URB of unanswered unlink request */
++ usbip_uinfo("unlink cleanup rx %lu\n", unlink->unlink_seqnum);
++
++ urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
++ if (!urb) {
++ usbip_uinfo("the urb (seqnum %lu) was already given back\n",
++ unlink->unlink_seqnum);
++ list_del(&unlink->list);
++ kfree(unlink);
++ continue;
++ }
++
++ urb->status = -ENODEV;
++
++ spin_lock(&the_controller->lock);
++ usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
++ spin_unlock(&the_controller->lock);
++
++ usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
++
+ list_del(&unlink->list);
+ kfree(unlink);
+ }
+--- a/drivers/staging/usbip/vhci_rx.c
++++ b/drivers/staging/usbip/vhci_rx.c
+@@ -23,16 +23,14 @@
+ #include "vhci.h"
+
+
+-/* get URB from transmitted urb queue */
+-static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
++/* get URB from transmitted urb queue. caller must hold vdev->priv_lock */
++struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
+ __u32 seqnum)
+ {
+ struct vhci_priv *priv, *tmp;
+ struct urb *urb = NULL;
+ int status;
+
+- spin_lock(&vdev->priv_lock);
+-
+ list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) {
+ if (priv->seqnum == seqnum) {
+ urb = priv->urb;
+@@ -63,8 +61,6 @@ static struct urb *pickup_urb_and_free_p
+ }
+ }
+
+- spin_unlock(&vdev->priv_lock);
+-
+ return urb;
+ }
+
+@@ -74,9 +70,11 @@ static void vhci_recv_ret_submit(struct
+ struct usbip_device *ud = &vdev->ud;
+ struct urb *urb;
+
++ spin_lock(&vdev->priv_lock);
+
+ urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
+
++ spin_unlock(&vdev->priv_lock);
+
+ if (!urb) {
+ usbip_uerr("cannot find a urb of seqnum %u\n",
+@@ -161,7 +159,12 @@ static void vhci_recv_ret_unlink(struct
+ return;
+ }
+
++ spin_lock(&vdev->priv_lock);
++
+ urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
++
++ spin_unlock(&vdev->priv_lock);
++
+ if (!urb) {
+ /*
+ * I get the result of a unlink request. But, it seems that I
--- /dev/null
+From 6d212153a838354078cc7d96f9bb23b7d1fd3d1b Mon Sep 17 00:00:00 2001
+From: Max Vozeler <max@vozeler.com>
+Date: Wed, 12 Jan 2011 15:02:02 +0200
+Subject: staging: usbip: vhci: refuse to enqueue for dead connections
+
+From: Max Vozeler <max@vozeler.com>
+
+commit 6d212153a838354078cc7d96f9bb23b7d1fd3d1b upstream.
+
+There can be requests to enqueue URBs while we are shutting
+down a connection.
+
+Signed-off-by: Max Vozeler <max@vozeler.com>
+Tested-by: Mark Wehby <MWehby@luxotticaRetail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/usbip/vhci_hcd.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/usbip/vhci_hcd.c
++++ b/drivers/staging/usbip/vhci_hcd.c
+@@ -559,6 +559,7 @@ static int vhci_urb_enqueue(struct usb_h
+ struct device *dev = &urb->dev->dev;
+ int ret = 0;
+ unsigned long flags;
++ struct vhci_device *vdev;
+
+ usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n",
+ hcd, urb, mem_flags);
+@@ -574,6 +575,18 @@ static int vhci_urb_enqueue(struct usb_h
+ return urb->status;
+ }
+
++ vdev = port_to_vdev(the_controller->pending_port);
++
++ /* refuse enqueue for dead connection */
++ spin_lock(&vdev->ud.lock);
++ if (vdev->ud.status == VDEV_ST_NULL || vdev->ud.status == VDEV_ST_ERROR) {
++ usbip_uerr("enqueue for inactive port %d\n", vdev->rhport);
++ spin_unlock(&vdev->ud.lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
++ return -ENODEV;
++ }
++ spin_unlock(&vdev->ud.lock);
++
+ ret = usb_hcd_link_urb_to_ep(hcd, urb);
+ if (ret)
+ goto no_need_unlink;
+@@ -592,8 +605,6 @@ static int vhci_urb_enqueue(struct usb_h
+ __u8 type = usb_pipetype(urb->pipe);
+ struct usb_ctrlrequest *ctrlreq =
+ (struct usb_ctrlrequest *) urb->setup_packet;
+- struct vhci_device *vdev =
+- port_to_vdev(the_controller->pending_port);
+
+ if (type != PIPE_CONTROL || !ctrlreq) {
+ dev_err(dev, "invalid request to devnum 0\n");
--- /dev/null
+From 7606ee8aa33287dd3e6eb44c78541b87a413a325 Mon Sep 17 00:00:00 2001
+From: Max Vozeler <max@vozeler.com>
+Date: Wed, 12 Jan 2011 15:02:00 +0200
+Subject: staging: usbip: vhci: update reference count for usb_device
+
+From: Max Vozeler <max@vozeler.com>
+
+commit 7606ee8aa33287dd3e6eb44c78541b87a413a325 upstream.
+
+This fixes an oops observed when reading status during
+removal of a device:
+
+[ 1706.648285] general protection fault: 0000 [#1] SMP
+[ 1706.648294] last sysfs file: /sys/devices/platform/vhci_hcd/status
+[ 1706.648297] CPU 1
+[ 1706.648300] Modules linked in: binfmt_misc microcode fuse loop vhci_hcd(N) usbip(N) usbcore usbip_common_mod(N) rtc_core rtc_lib joydev dm_mirror dm_region_hash dm_log linear dm_snapshot xennet dm_mod ext3 mbcache jbd processor thermal_sys hwmon xenblk cdrom
+[ 1706.648324] Supported: Yes
+[ 1706.648327] Pid: 10422, comm: usbip Tainted: G N 2.6.32.12-0.7-xen #1
+[ 1706.648330] RIP: e030:[<ffffffff801b10d5>] [<ffffffff801b10d5>] strnlen+0x5/0x40
+[ 1706.648340] RSP: e02b:ffff8800a994dd30 EFLAGS: 00010286
+[ 1706.648343] RAX: ffffffff80481ec1 RBX: 0000000000000000 RCX: 0000000000000002
+[ 1706.648347] RDX: 00200d1d4f1c001c RSI: ffffffffffffffff RDI: 00200d1d4f1c001c
+[ 1706.648350] RBP: ffff880129a1c0aa R08: ffffffffa01901c4 R09: 0000000000000006
+[ 1706.648353] R10: 0000000000000000 R11: 0000000000000000 R12: ffff8800a9a1c0ab
+[ 1706.648357] R13: 00200d1d4f1c001c R14: 00000000ffffffff R15: ffff880129a1c0aa
+[ 1706.648363] FS: 00007f2f2e9ca700(0000) GS:ffff880001018000(0000) knlGS:0000000000000000
+[ 1706.648367] CS: e033 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 1706.648370] CR2: 000000000071b048 CR3: 00000000b4b68000 CR4: 0000000000002660
+[ 1706.648374] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 1706.648378] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+[ 1706.648381] Process usbip (pid: 10422, threadinfo ffff8800a994c000, task ffff88007b170200)
+[ 1706.648385] Stack:
+[ 1706.648387] ffffffff801b28c9 0000000000000002 ffffffffa01901c4 ffff8800a9a1c0ab
+[ 1706.648391] <0> ffffffffa01901c6 ffff8800a994de08 ffffffff801b339b 0000000000000004
+[ 1706.648397] <0> 0000000affffffff ffffffffffffffff 00000000000067c0 0000000000000000
+[ 1706.648404] Call Trace:
+[ 1706.648413] [<ffffffff801b28c9>] string+0x39/0xe0
+[ 1706.648419] [<ffffffff801b339b>] vsnprintf+0x1eb/0x620
+[ 1706.648423] [<ffffffff801b3813>] sprintf+0x43/0x50
+[ 1706.648429] [<ffffffffa018d719>] show_status+0x1b9/0x220 [vhci_hcd]
+[ 1706.648438] [<ffffffff8024a2b7>] dev_attr_show+0x27/0x60
+[ 1706.648445] [<ffffffff80144821>] sysfs_read_file+0x101/0x1d0
+[ 1706.648451] [<ffffffff800da4a7>] vfs_read+0xc7/0x130
+[ 1706.648457] [<ffffffff800da613>] sys_read+0x53/0xa0
+[ 1706.648462] [<ffffffff80007458>] system_call_fastpath+0x16/0x1b
+[ 1706.648468] [<00007f2f2de40f30>] 0x7f2f2de40f30
+[ 1706.648470] Code: 66 0f 1f 44 00 00 48 83 c2 01 80 3a 00 75 f7 48 89 d0 48 29 f8 f3 c3 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 48 85 f6 74 29 <80> 3f 00 74 24 48 8d 56 ff 48 89 f8 eb 0e 0f 1f 44 00 00 48 83
+[ 1706.648507] RIP [<ffffffff801b10d5>] strnlen+0x5/0x40
+[ 1706.648511] RSP <ffff8800a994dd30>
+[ 1706.649575] ---[ end trace b4eb72bf2e149593 ]---
+
+Signed-off-by: Max Vozeler <max@vozeler.com>
+Tested-by: Mark Wehby <MWehby@luxotticaRetail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/usbip/vhci_hcd.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/usbip/vhci_hcd.c
++++ b/drivers/staging/usbip/vhci_hcd.c
+@@ -607,7 +607,9 @@ static int vhci_urb_enqueue(struct usb_h
+ dev_info(dev, "SetAddress Request (%d) to port %d\n",
+ ctrlreq->wValue, vdev->rhport);
+
+- vdev->udev = urb->dev;
++ if (vdev->udev)
++ usb_put_dev(vdev->udev);
++ vdev->udev = usb_get_dev(urb->dev);
+
+ spin_lock(&vdev->ud.lock);
+ vdev->ud.status = VDEV_ST_USED;
+@@ -627,8 +629,9 @@ static int vhci_urb_enqueue(struct usb_h
+ "Get_Descriptor to device 0 "
+ "(get max pipe size)\n");
+
+- /* FIXME: reference count? (usb_get_dev()) */
+- vdev->udev = urb->dev;
++ if (vdev->udev)
++ usb_put_dev(vdev->udev);
++ vdev->udev = usb_get_dev(urb->dev);
+ goto out;
+
+ default:
+@@ -887,6 +890,10 @@ static void vhci_device_reset(struct usb
+ vdev->speed = 0;
+ vdev->devid = 0;
+
++ if (vdev->udev)
++ usb_put_dev(vdev->udev);
++ vdev->udev = NULL;
++
+ ud->tcp_socket = NULL;
+
+ ud->status = VDEV_ST_NULL;
--- /dev/null
+From 01446ef5af4e8802369bf4d257806e24345a9371 Mon Sep 17 00:00:00 2001
+From: Max Vozeler <max@vozeler.com>
+Date: Wed, 12 Jan 2011 15:02:05 +0200
+Subject: staging: usbip: vhci: use urb->dev->portnum to find port
+
+From: Max Vozeler <max@vozeler.com>
+
+commit 01446ef5af4e8802369bf4d257806e24345a9371 upstream.
+
+The access to pending_port was racy when two devices
+were being attached at the same time.
+
+Signed-off-by: Max Vozeler <max@vozeler.com>
+Tested-by: Mark Wehby <MWehby@luxotticaRetail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/usbip/vhci.h | 3 ---
+ drivers/staging/usbip/vhci_hcd.c | 4 +---
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/staging/usbip/vhci.h
++++ b/drivers/staging/usbip/vhci.h
+@@ -100,9 +100,6 @@ struct vhci_hcd {
+ * But, the index of this array begins from 0.
+ */
+ struct vhci_device vdev[VHCI_NPORTS];
+-
+- /* vhci_device which has not been assiged its address yet */
+- int pending_port;
+ };
+
+
+--- a/drivers/staging/usbip/vhci_hcd.c
++++ b/drivers/staging/usbip/vhci_hcd.c
+@@ -138,8 +138,6 @@ void rh_port_connect(int rhport, enum us
+ * the_controller->vdev[rhport].ud.status = VDEV_CONNECT;
+ * spin_unlock(&the_controller->vdev[rhport].ud.lock); */
+
+- the_controller->pending_port = rhport;
+-
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ usb_hcd_poll_rh_status(vhci_to_hcd(the_controller));
+@@ -575,7 +573,7 @@ static int vhci_urb_enqueue(struct usb_h
+ return urb->status;
+ }
+
+- vdev = port_to_vdev(the_controller->pending_port);
++ vdev = port_to_vdev(urb->dev->portnum-1);
+
+ /* refuse enqueue for dead connection */
+ spin_lock(&vdev->ud.lock);