diff options
Diffstat (limited to 'drivers/usb/wusbcore/devconnect.c')
| -rw-r--r-- | drivers/usb/wusbcore/devconnect.c | 72 |
1 files changed, 27 insertions, 45 deletions
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index e538b72c4e3a..f14e7929ba22 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
| @@ -97,18 +97,12 @@ static void wusbhc_devconnect_acked_work(struct work_struct *work); | |||
| 97 | 97 | ||
| 98 | static void wusb_dev_free(struct wusb_dev *wusb_dev) | 98 | static void wusb_dev_free(struct wusb_dev *wusb_dev) |
| 99 | { | 99 | { |
| 100 | if (wusb_dev) { | 100 | kfree(wusb_dev); |
| 101 | kfree(wusb_dev->set_gtk_req); | ||
| 102 | usb_free_urb(wusb_dev->set_gtk_urb); | ||
| 103 | kfree(wusb_dev); | ||
| 104 | } | ||
| 105 | } | 101 | } |
| 106 | 102 | ||
| 107 | static struct wusb_dev *wusb_dev_alloc(struct wusbhc *wusbhc) | 103 | static struct wusb_dev *wusb_dev_alloc(struct wusbhc *wusbhc) |
| 108 | { | 104 | { |
| 109 | struct wusb_dev *wusb_dev; | 105 | struct wusb_dev *wusb_dev; |
| 110 | struct urb *urb; | ||
| 111 | struct usb_ctrlrequest *req; | ||
| 112 | 106 | ||
| 113 | wusb_dev = kzalloc(sizeof(*wusb_dev), GFP_KERNEL); | 107 | wusb_dev = kzalloc(sizeof(*wusb_dev), GFP_KERNEL); |
| 114 | if (wusb_dev == NULL) | 108 | if (wusb_dev == NULL) |
| @@ -118,22 +112,6 @@ static struct wusb_dev *wusb_dev_alloc(struct wusbhc *wusbhc) | |||
| 118 | 112 | ||
| 119 | INIT_WORK(&wusb_dev->devconnect_acked_work, wusbhc_devconnect_acked_work); | 113 | INIT_WORK(&wusb_dev->devconnect_acked_work, wusbhc_devconnect_acked_work); |
| 120 | 114 | ||
| 121 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 122 | if (urb == NULL) | ||
| 123 | goto err; | ||
| 124 | wusb_dev->set_gtk_urb = urb; | ||
| 125 | |||
| 126 | req = kmalloc(sizeof(*req), GFP_KERNEL); | ||
| 127 | if (req == NULL) | ||
| 128 | goto err; | ||
| 129 | wusb_dev->set_gtk_req = req; | ||
| 130 | |||
| 131 | req->bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE; | ||
| 132 | req->bRequest = USB_REQ_SET_DESCRIPTOR; | ||
| 133 | req->wValue = cpu_to_le16(USB_DT_KEY << 8 | wusbhc->gtk_index); | ||
| 134 | req->wIndex = 0; | ||
| 135 | req->wLength = cpu_to_le16(wusbhc->gtk.descr.bLength); | ||
| 136 | |||
| 137 | return wusb_dev; | 115 | return wusb_dev; |
| 138 | err: | 116 | err: |
| 139 | wusb_dev_free(wusb_dev); | 117 | wusb_dev_free(wusb_dev); |
| @@ -411,9 +389,6 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, | |||
| 411 | /* | 389 | /* |
| 412 | * Refresh the list of keep alives to emit in the MMC | 390 | * Refresh the list of keep alives to emit in the MMC |
| 413 | * | 391 | * |
| 414 | * Some devices don't respond to keep alives unless they've been | ||
| 415 | * authenticated, so skip unauthenticated devices. | ||
| 416 | * | ||
| 417 | * We only publish the first four devices that have a coming timeout | 392 | * We only publish the first four devices that have a coming timeout |
| 418 | * condition. Then when we are done processing those, we go for the | 393 | * condition. Then when we are done processing those, we go for the |
| 419 | * next ones. We ignore the ones that have timed out already (they'll | 394 | * next ones. We ignore the ones that have timed out already (they'll |
| @@ -448,7 +423,7 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc) | |||
| 448 | 423 | ||
| 449 | if (wusb_dev == NULL) | 424 | if (wusb_dev == NULL) |
| 450 | continue; | 425 | continue; |
| 451 | if (wusb_dev->usb_dev == NULL || !wusb_dev->usb_dev->authenticated) | 426 | if (wusb_dev->usb_dev == NULL) |
| 452 | continue; | 427 | continue; |
| 453 | 428 | ||
| 454 | if (time_after(jiffies, wusb_dev->entry_ts + tt)) { | 429 | if (time_after(jiffies, wusb_dev->entry_ts + tt)) { |
| @@ -524,11 +499,19 @@ static struct wusb_dev *wusbhc_find_dev_by_addr(struct wusbhc *wusbhc, u8 addr) | |||
| 524 | * | 499 | * |
| 525 | * @wusbhc shall be referenced and unlocked | 500 | * @wusbhc shall be referenced and unlocked |
| 526 | */ | 501 | */ |
| 527 | static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | 502 | static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, u8 srcaddr) |
| 528 | { | 503 | { |
| 504 | struct wusb_dev *wusb_dev; | ||
| 505 | |||
| 529 | mutex_lock(&wusbhc->mutex); | 506 | mutex_lock(&wusbhc->mutex); |
| 530 | wusb_dev->entry_ts = jiffies; | 507 | wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr); |
| 531 | __wusbhc_keep_alive(wusbhc); | 508 | if (wusb_dev == NULL) { |
| 509 | dev_dbg(wusbhc->dev, "ignoring DN_Alive from unconnected device %02x\n", | ||
| 510 | srcaddr); | ||
| 511 | } else { | ||
| 512 | wusb_dev->entry_ts = jiffies; | ||
| 513 | __wusbhc_keep_alive(wusbhc); | ||
| 514 | } | ||
| 532 | mutex_unlock(&wusbhc->mutex); | 515 | mutex_unlock(&wusbhc->mutex); |
| 533 | } | 516 | } |
| 534 | 517 | ||
| @@ -582,14 +565,22 @@ static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc, | |||
| 582 | * | 565 | * |
| 583 | * @wusbhc shall be referenced and unlocked | 566 | * @wusbhc shall be referenced and unlocked |
| 584 | */ | 567 | */ |
| 585 | static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | 568 | static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, u8 srcaddr) |
| 586 | { | 569 | { |
| 587 | struct device *dev = wusbhc->dev; | 570 | struct device *dev = wusbhc->dev; |
| 588 | 571 | struct wusb_dev *wusb_dev; | |
| 589 | dev_info(dev, "DN DISCONNECT: device 0x%02x going down\n", wusb_dev->addr); | ||
| 590 | 572 | ||
| 591 | mutex_lock(&wusbhc->mutex); | 573 | mutex_lock(&wusbhc->mutex); |
| 592 | __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, wusb_dev->port_idx)); | 574 | wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr); |
| 575 | if (wusb_dev == NULL) { | ||
| 576 | dev_dbg(dev, "ignoring DN DISCONNECT from unconnected device %02x\n", | ||
| 577 | srcaddr); | ||
| 578 | } else { | ||
| 579 | dev_info(dev, "DN DISCONNECT: device 0x%02x going down\n", | ||
| 580 | wusb_dev->addr); | ||
| 581 | __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, | ||
| 582 | wusb_dev->port_idx)); | ||
| 583 | } | ||
| 593 | mutex_unlock(&wusbhc->mutex); | 584 | mutex_unlock(&wusbhc->mutex); |
| 594 | } | 585 | } |
| 595 | 586 | ||
| @@ -611,30 +602,21 @@ void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr, | |||
| 611 | struct wusb_dn_hdr *dn_hdr, size_t size) | 602 | struct wusb_dn_hdr *dn_hdr, size_t size) |
| 612 | { | 603 | { |
| 613 | struct device *dev = wusbhc->dev; | 604 | struct device *dev = wusbhc->dev; |
| 614 | struct wusb_dev *wusb_dev; | ||
| 615 | 605 | ||
| 616 | if (size < sizeof(struct wusb_dn_hdr)) { | 606 | if (size < sizeof(struct wusb_dn_hdr)) { |
| 617 | dev_err(dev, "DN data shorter than DN header (%d < %d)\n", | 607 | dev_err(dev, "DN data shorter than DN header (%d < %d)\n", |
| 618 | (int)size, (int)sizeof(struct wusb_dn_hdr)); | 608 | (int)size, (int)sizeof(struct wusb_dn_hdr)); |
| 619 | return; | 609 | return; |
| 620 | } | 610 | } |
| 621 | |||
| 622 | wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr); | ||
| 623 | if (wusb_dev == NULL && dn_hdr->bType != WUSB_DN_CONNECT) { | ||
| 624 | dev_dbg(dev, "ignoring DN %d from unconnected device %02x\n", | ||
| 625 | dn_hdr->bType, srcaddr); | ||
| 626 | return; | ||
| 627 | } | ||
| 628 | |||
| 629 | switch (dn_hdr->bType) { | 611 | switch (dn_hdr->bType) { |
| 630 | case WUSB_DN_CONNECT: | 612 | case WUSB_DN_CONNECT: |
| 631 | wusbhc_handle_dn_connect(wusbhc, dn_hdr, size); | 613 | wusbhc_handle_dn_connect(wusbhc, dn_hdr, size); |
| 632 | break; | 614 | break; |
| 633 | case WUSB_DN_ALIVE: | 615 | case WUSB_DN_ALIVE: |
| 634 | wusbhc_handle_dn_alive(wusbhc, wusb_dev); | 616 | wusbhc_handle_dn_alive(wusbhc, srcaddr); |
| 635 | break; | 617 | break; |
| 636 | case WUSB_DN_DISCONNECT: | 618 | case WUSB_DN_DISCONNECT: |
| 637 | wusbhc_handle_dn_disconnect(wusbhc, wusb_dev); | 619 | wusbhc_handle_dn_disconnect(wusbhc, srcaddr); |
| 638 | break; | 620 | break; |
| 639 | case WUSB_DN_MASAVAILCHANGED: | 621 | case WUSB_DN_MASAVAILCHANGED: |
| 640 | case WUSB_DN_RWAKE: | 622 | case WUSB_DN_RWAKE: |
