diff options
Diffstat (limited to 'drivers/usb/wusbcore')
-rw-r--r-- | drivers/usb/wusbcore/Kconfig | 2 | ||||
-rw-r--r-- | drivers/usb/wusbcore/crypto.c | 2 | ||||
-rw-r--r-- | drivers/usb/wusbcore/devconnect.c | 6 | ||||
-rw-r--r-- | drivers/usb/wusbcore/security.c | 17 | ||||
-rw-r--r-- | drivers/usb/wusbcore/wa-hc.h | 2 | ||||
-rw-r--r-- | drivers/usb/wusbcore/wa-xfer.c | 17 | ||||
-rw-r--r-- | drivers/usb/wusbcore/wusbhc.h | 3 |
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 | # |
4 | config USB_WUSB | 4 | config 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 | ||
19 | config USB_WUSB_CBAF | 18 | config 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 | ||
34 | int wusbhc_sec_create(struct wusbhc *wusbhc) | 34 | int 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 */ |
49 | void wusbhc_sec_destroy(struct wusbhc *wusbhc) | 63 | void 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; |