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 @@ # config USB_WUSB tristate "Enable Wireless USB extensions" - depends on PCI depends on UWB select CRYPTO select CRYPTO_BLKCIPHER @@ -18,6 +17,7 @@ config USB_WUSB config USB_WUSB_CBAF tristate "Support WUSB Cable Based Association (CBA)" + depends on USB help Some WUSB devices support Cable Based Association. It's used to 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, WARN_ON(sizeof(ax) != sizeof(struct aes_ccm_block)); result = -ENOMEM; - zero_padding = sizeof(struct aes_ccm_block) - - blen % sizeof(struct aes_ccm_block); zero_padding = blen % sizeof(struct aes_ccm_block); if (zero_padding) 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, port->wusb_dev = wusb_dev; port->status |= USB_PORT_STAT_CONNECTION; port->change |= USB_PORT_STAT_C_CONNECTION; - /* Now the port status changed to connected; khubd will + /* Now the port status changed to connected; hub_wq will * pick the change up and try to reset the port to bring it to * the enabled state--so this process returns up to the stack * and it calls back into wusbhc_rh_port_reset(). @@ -343,7 +343,7 @@ error_unlock: /* * Disconnect a Wireless USB device from its fake port * - * Marks the port as disconnected so that khubd can pick up the change + * Marks the port as disconnected so that hub_wq can pick up the change * and drops our knowledge about the device. * * Assumes there is a device connected @@ -379,7 +379,7 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, wusbhc_gtk_rekey(wusbhc); /* The Wireless USB part has forgotten about the device already; now - * khubd's timer will pick up the disconnection and remove the USB + * hub_wq's timer will pick up the disconnection and remove the USB * device from the system */ } 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); int wusbhc_sec_create(struct wusbhc *wusbhc) { + /* + * WQ is singlethread because we need to serialize rekey operations. + * Use a separate workqueue for security operations instead of the + * wusbd workqueue because security operations may need to communicate + * directly with downstream wireless devices using synchronous URBs. + * If a device is not responding, this could block other host + * controller operations. + */ + wusbhc->wq_security = create_singlethread_workqueue("wusbd_security"); + if (wusbhc->wq_security == NULL) { + pr_err("WUSB-core: Cannot create wusbd_security workqueue\n"); + return -ENOMEM; + } + wusbhc->gtk.descr.bLength = sizeof(wusbhc->gtk.descr) + sizeof(wusbhc->gtk.data); wusbhc->gtk.descr.bDescriptorType = USB_DT_KEY; @@ -48,6 +62,7 @@ int wusbhc_sec_create(struct wusbhc *wusbhc) /* Called when the HC is destroyed */ void wusbhc_sec_destroy(struct wusbhc *wusbhc) { + destroy_workqueue(wusbhc->wq_security); } @@ -596,5 +611,5 @@ void wusbhc_gtk_rekey(struct wusbhc *wusbhc) * and will cause a deadlock. Instead, queue a work item to do * it when the lock is not held */ - queue_work(wusbd, &wusbhc->gtk_rekey_work); + queue_work(wusbhc->wq_security, &wusbhc->gtk_rekey_work); } 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 @@ * * Note much of the activity is difficult to follow. For example a * device connect goes to devconnect, which will cause the "fake" root - * hub port to show a connect and stop there. Then khubd will notice + * hub port to show a connect and stop there. Then hub_wq will notice * and call into the rh.c:hwahc_rc_port_reset() code to authenticate * the device (and this might require user intervention) and enable * 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) __func__, urb->status); if (xfer) { unsigned long flags; - int done; + int done, seg_index = 0; struct wa_rpipe *rpipe = xfer->ep->hcpriv; dev_err(dev, "%s: cleaning up xfer %p ID 0x%08X.\n", __func__, xfer, wa_xfer_id(xfer)); spin_lock_irqsave(&xfer->lock, flags); - /* mark all segs as aborted. */ - wa_complete_remaining_xfer_segs(xfer, 0, + /* skip done segs. */ + while (seg_index < xfer->segs) { + struct wa_seg *seg = xfer->seg[seg_index]; + + if ((seg->status == WA_SEG_DONE) || + (seg->status == WA_SEG_ERROR)) { + ++seg_index; + } else { + break; + } + } + /* mark remaining segs as aborted. */ + wa_complete_remaining_xfer_segs(xfer, seg_index, WA_SEG_ABORTED); done = __wa_xfer_is_done(xfer); 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 { } __attribute__((packed)) gtk; u8 gtk_index; u32 gtk_tkid; + + /* workqueue for WUSB security related tasks. */ + struct workqueue_struct *wq_security; struct work_struct gtk_rekey_work; struct usb_encryption_descriptor *ccm1_etd; |