aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/wusbcore
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/wusbcore')
-rw-r--r--drivers/usb/wusbcore/Kconfig2
-rw-r--r--drivers/usb/wusbcore/crypto.c2
-rw-r--r--drivers/usb/wusbcore/devconnect.c6
-rw-r--r--drivers/usb/wusbcore/security.c17
-rw-r--r--drivers/usb/wusbcore/wa-hc.h2
-rw-r--r--drivers/usb/wusbcore/wa-xfer.c17
-rw-r--r--drivers/usb/wusbcore/wusbhc.h3
7 files changed, 38 insertions, 11 deletions
diff --git a/drivers/usb/wusbcore/Kconfig b/drivers/usb/wusbcore/Kconfig
index 0e17b966e1b4..348de1d6726e 100644
--- a/drivers/usb/wusbcore/Kconfig
+++ b/drivers/usb/wusbcore/Kconfig
@@ -3,7 +3,6 @@
3# 3#
4config USB_WUSB 4config USB_WUSB
5 tristate "Enable Wireless USB extensions" 5 tristate "Enable Wireless USB extensions"
6 depends on PCI
7 depends on UWB 6 depends on UWB
8 select CRYPTO 7 select CRYPTO
9 select CRYPTO_BLKCIPHER 8 select CRYPTO_BLKCIPHER
@@ -18,6 +17,7 @@ config USB_WUSB
18 17
19config USB_WUSB_CBAF 18config USB_WUSB_CBAF
20 tristate "Support WUSB Cable Based Association (CBA)" 19 tristate "Support WUSB Cable Based Association (CBA)"
20 depends on USB
21 help 21 help
22 Some WUSB devices support Cable Based Association. It's used to 22 Some WUSB devices support Cable Based Association. It's used to
23 enable the secure communication between the host and the 23 enable the secure communication between the host and the
diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c
index 9a95b2dc6d1b..50ce80d604f3 100644
--- a/drivers/usb/wusbcore/crypto.c
+++ b/drivers/usb/wusbcore/crypto.c
@@ -222,8 +222,6 @@ static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc,
222 WARN_ON(sizeof(ax) != sizeof(struct aes_ccm_block)); 222 WARN_ON(sizeof(ax) != sizeof(struct aes_ccm_block));
223 223
224 result = -ENOMEM; 224 result = -ENOMEM;
225 zero_padding = sizeof(struct aes_ccm_block)
226 - blen % sizeof(struct aes_ccm_block);
227 zero_padding = blen % sizeof(struct aes_ccm_block); 225 zero_padding = blen % sizeof(struct aes_ccm_block);
228 if (zero_padding) 226 if (zero_padding)
229 zero_padding = sizeof(struct aes_ccm_block) - zero_padding; 227 zero_padding = sizeof(struct aes_ccm_block) - zero_padding;
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index 0677139c6065..3f4f5fbded55 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -329,7 +329,7 @@ void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc,
329 port->wusb_dev = wusb_dev; 329 port->wusb_dev = wusb_dev;
330 port->status |= USB_PORT_STAT_CONNECTION; 330 port->status |= USB_PORT_STAT_CONNECTION;
331 port->change |= USB_PORT_STAT_C_CONNECTION; 331 port->change |= USB_PORT_STAT_C_CONNECTION;
332 /* Now the port status changed to connected; khubd will 332 /* Now the port status changed to connected; hub_wq will
333 * pick the change up and try to reset the port to bring it to 333 * pick the change up and try to reset the port to bring it to
334 * the enabled state--so this process returns up to the stack 334 * the enabled state--so this process returns up to the stack
335 * and it calls back into wusbhc_rh_port_reset(). 335 * and it calls back into wusbhc_rh_port_reset().
@@ -343,7 +343,7 @@ error_unlock:
343/* 343/*
344 * Disconnect a Wireless USB device from its fake port 344 * Disconnect a Wireless USB device from its fake port
345 * 345 *
346 * Marks the port as disconnected so that khubd can pick up the change 346 * Marks the port as disconnected so that hub_wq can pick up the change
347 * and drops our knowledge about the device. 347 * and drops our knowledge about the device.
348 * 348 *
349 * Assumes there is a device connected 349 * Assumes there is a device connected
@@ -379,7 +379,7 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
379 wusbhc_gtk_rekey(wusbhc); 379 wusbhc_gtk_rekey(wusbhc);
380 380
381 /* The Wireless USB part has forgotten about the device already; now 381 /* The Wireless USB part has forgotten about the device already; now
382 * khubd's timer will pick up the disconnection and remove the USB 382 * hub_wq's timer will pick up the disconnection and remove the USB
383 * device from the system 383 * device from the system
384 */ 384 */
385} 385}
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index 95be9953cd47..cc74d669c802 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -33,6 +33,20 @@ static void wusbhc_gtk_rekey_work(struct work_struct *work);
33 33
34int wusbhc_sec_create(struct wusbhc *wusbhc) 34int wusbhc_sec_create(struct wusbhc *wusbhc)
35{ 35{
36 /*
37 * WQ is singlethread because we need to serialize rekey operations.
38 * Use a separate workqueue for security operations instead of the
39 * wusbd workqueue because security operations may need to communicate
40 * directly with downstream wireless devices using synchronous URBs.
41 * If a device is not responding, this could block other host
42 * controller operations.
43 */
44 wusbhc->wq_security = create_singlethread_workqueue("wusbd_security");
45 if (wusbhc->wq_security == NULL) {
46 pr_err("WUSB-core: Cannot create wusbd_security workqueue\n");
47 return -ENOMEM;
48 }
49
36 wusbhc->gtk.descr.bLength = sizeof(wusbhc->gtk.descr) + 50 wusbhc->gtk.descr.bLength = sizeof(wusbhc->gtk.descr) +
37 sizeof(wusbhc->gtk.data); 51 sizeof(wusbhc->gtk.data);
38 wusbhc->gtk.descr.bDescriptorType = USB_DT_KEY; 52 wusbhc->gtk.descr.bDescriptorType = USB_DT_KEY;
@@ -48,6 +62,7 @@ int wusbhc_sec_create(struct wusbhc *wusbhc)
48/* Called when the HC is destroyed */ 62/* Called when the HC is destroyed */
49void wusbhc_sec_destroy(struct wusbhc *wusbhc) 63void wusbhc_sec_destroy(struct wusbhc *wusbhc)
50{ 64{
65 destroy_workqueue(wusbhc->wq_security);
51} 66}
52 67
53 68
@@ -596,5 +611,5 @@ void wusbhc_gtk_rekey(struct wusbhc *wusbhc)
596 * and will cause a deadlock. Instead, queue a work item to do 611 * and will cause a deadlock. Instead, queue a work item to do
597 * it when the lock is not held 612 * it when the lock is not held
598 */ 613 */
599 queue_work(wusbd, &wusbhc->gtk_rekey_work); 614 queue_work(wusbhc->wq_security, &wusbhc->gtk_rekey_work);
600} 615}
diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/usb/wusbcore/wa-hc.h
index f2a8d29e17b9..edc7267157f3 100644
--- a/drivers/usb/wusbcore/wa-hc.h
+++ b/drivers/usb/wusbcore/wa-hc.h
@@ -64,7 +64,7 @@
64 * 64 *
65 * Note much of the activity is difficult to follow. For example a 65 * Note much of the activity is difficult to follow. For example a
66 * device connect goes to devconnect, which will cause the "fake" root 66 * device connect goes to devconnect, which will cause the "fake" root
67 * hub port to show a connect and stop there. Then khubd will notice 67 * hub port to show a connect and stop there. Then hub_wq will notice
68 * and call into the rh.c:hwahc_rc_port_reset() code to authenticate 68 * and call into the rh.c:hwahc_rc_port_reset() code to authenticate
69 * the device (and this might require user intervention) and enable 69 * the device (and this might require user intervention) and enable
70 * the port. 70 * the port.
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c
index e279015be466..69af4fd9e072 100644
--- a/drivers/usb/wusbcore/wa-xfer.c
+++ b/drivers/usb/wusbcore/wa-xfer.c
@@ -459,14 +459,25 @@ static void __wa_xfer_abort_cb(struct urb *urb)
459 __func__, urb->status); 459 __func__, urb->status);
460 if (xfer) { 460 if (xfer) {
461 unsigned long flags; 461 unsigned long flags;
462 int done; 462 int done, seg_index = 0;
463 struct wa_rpipe *rpipe = xfer->ep->hcpriv; 463 struct wa_rpipe *rpipe = xfer->ep->hcpriv;
464 464
465 dev_err(dev, "%s: cleaning up xfer %p ID 0x%08X.\n", 465 dev_err(dev, "%s: cleaning up xfer %p ID 0x%08X.\n",
466 __func__, xfer, wa_xfer_id(xfer)); 466 __func__, xfer, wa_xfer_id(xfer));
467 spin_lock_irqsave(&xfer->lock, flags); 467 spin_lock_irqsave(&xfer->lock, flags);
468 /* mark all segs as aborted. */ 468 /* skip done segs. */
469 wa_complete_remaining_xfer_segs(xfer, 0, 469 while (seg_index < xfer->segs) {
470 struct wa_seg *seg = xfer->seg[seg_index];
471
472 if ((seg->status == WA_SEG_DONE) ||
473 (seg->status == WA_SEG_ERROR)) {
474 ++seg_index;
475 } else {
476 break;
477 }
478 }
479 /* mark remaining segs as aborted. */
480 wa_complete_remaining_xfer_segs(xfer, seg_index,
470 WA_SEG_ABORTED); 481 WA_SEG_ABORTED);
471 done = __wa_xfer_is_done(xfer); 482 done = __wa_xfer_is_done(xfer);
472 spin_unlock_irqrestore(&xfer->lock, flags); 483 spin_unlock_irqrestore(&xfer->lock, flags);
diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h
index 2384add45371..41838db7f85c 100644
--- a/drivers/usb/wusbcore/wusbhc.h
+++ b/drivers/usb/wusbcore/wusbhc.h
@@ -295,6 +295,9 @@ struct wusbhc {
295 } __attribute__((packed)) gtk; 295 } __attribute__((packed)) gtk;
296 u8 gtk_index; 296 u8 gtk_index;
297 u32 gtk_tkid; 297 u32 gtk_tkid;
298
299 /* workqueue for WUSB security related tasks. */
300 struct workqueue_struct *wq_security;
298 struct work_struct gtk_rekey_work; 301 struct work_struct gtk_rekey_work;
299 302
300 struct usb_encryption_descriptor *ccm1_etd; 303 struct usb_encryption_descriptor *ccm1_etd;