diff options
Diffstat (limited to 'drivers/usb/wusbcore')
-rw-r--r-- | drivers/usb/wusbcore/devconnect.c | 21 | ||||
-rw-r--r-- | drivers/usb/wusbcore/wusbhc.c | 32 |
2 files changed, 31 insertions, 22 deletions
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 386eaa22d215..4ac4300a3f9a 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
@@ -267,6 +267,8 @@ static void wusbhc_devconnect_acked_work(struct work_struct *work) | |||
267 | mutex_lock(&wusbhc->mutex); | 267 | mutex_lock(&wusbhc->mutex); |
268 | wusbhc_devconnect_acked(wusbhc, wusb_dev); | 268 | wusbhc_devconnect_acked(wusbhc, wusb_dev); |
269 | mutex_unlock(&wusbhc->mutex); | 269 | mutex_unlock(&wusbhc->mutex); |
270 | |||
271 | wusb_dev_put(wusb_dev); | ||
270 | } | 272 | } |
271 | 273 | ||
272 | /* | 274 | /* |
@@ -396,7 +398,8 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, | |||
396 | 398 | ||
397 | /* After a device disconnects, change the GTK (see [WUSB] | 399 | /* After a device disconnects, change the GTK (see [WUSB] |
398 | * section 6.2.11.2). */ | 400 | * section 6.2.11.2). */ |
399 | wusbhc_gtk_rekey(wusbhc); | 401 | if (wusbhc->active) |
402 | wusbhc_gtk_rekey(wusbhc); | ||
400 | 403 | ||
401 | /* The Wireless USB part has forgotten about the device already; now | 404 | /* The Wireless USB part has forgotten about the device already; now |
402 | * khubd's timer will pick up the disconnection and remove the USB | 405 | * khubd's timer will pick up the disconnection and remove the USB |
@@ -1084,15 +1087,21 @@ error_mmcie_set: | |||
1084 | * wusbhc_devconnect_stop - stop managing connected devices | 1087 | * wusbhc_devconnect_stop - stop managing connected devices |
1085 | * @wusbhc: the WUSB HC | 1088 | * @wusbhc: the WUSB HC |
1086 | * | 1089 | * |
1087 | * Removes the Host Info IE and stops the keep alives. | 1090 | * Disconnects any devices still connected, stops the keep alives and |
1088 | * | 1091 | * removes the Host Info IE. |
1089 | * FIXME: should this disconnect all devices? | ||
1090 | */ | 1092 | */ |
1091 | void wusbhc_devconnect_stop(struct wusbhc *wusbhc) | 1093 | void wusbhc_devconnect_stop(struct wusbhc *wusbhc) |
1092 | { | 1094 | { |
1093 | cancel_delayed_work_sync(&wusbhc->keep_alive_timer); | 1095 | int i; |
1094 | WARN_ON(!list_empty(&wusbhc->cack_list)); | ||
1095 | 1096 | ||
1097 | mutex_lock(&wusbhc->mutex); | ||
1098 | for (i = 0; i < wusbhc->ports_max; i++) { | ||
1099 | if (wusbhc->port[i].wusb_dev) | ||
1100 | __wusbhc_dev_disconnect(wusbhc, &wusbhc->port[i]); | ||
1101 | } | ||
1102 | mutex_unlock(&wusbhc->mutex); | ||
1103 | |||
1104 | cancel_delayed_work_sync(&wusbhc->keep_alive_timer); | ||
1096 | wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr); | 1105 | wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr); |
1097 | kfree(wusbhc->wuie_host_info); | 1106 | kfree(wusbhc->wuie_host_info); |
1098 | wusbhc->wuie_host_info = NULL; | 1107 | wusbhc->wuie_host_info = NULL; |
diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c index 07c63a31c799..ee6256f23636 100644 --- a/drivers/usb/wusbcore/wusbhc.c +++ b/drivers/usb/wusbcore/wusbhc.c | |||
@@ -88,33 +88,31 @@ static DEVICE_ATTR(wusb_trust_timeout, 0644, wusb_trust_timeout_show, | |||
88 | wusb_trust_timeout_store); | 88 | wusb_trust_timeout_store); |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * Show & store the current WUSB CHID | 91 | * Show the current WUSB CHID. |
92 | */ | 92 | */ |
93 | static ssize_t wusb_chid_show(struct device *dev, | 93 | static ssize_t wusb_chid_show(struct device *dev, |
94 | struct device_attribute *attr, char *buf) | 94 | struct device_attribute *attr, char *buf) |
95 | { | 95 | { |
96 | struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); | 96 | struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); |
97 | const struct wusb_ckhdid *chid; | ||
97 | ssize_t result = 0; | 98 | ssize_t result = 0; |
98 | 99 | ||
99 | if (wusbhc->wuie_host_info != NULL) | 100 | if (wusbhc->wuie_host_info != NULL) |
100 | result += ckhdid_printf(buf, PAGE_SIZE, | 101 | chid = &wusbhc->wuie_host_info->CHID; |
101 | &wusbhc->wuie_host_info->CHID); | 102 | else |
103 | chid = &wusb_ckhdid_zero; | ||
104 | |||
105 | result += ckhdid_printf(buf, PAGE_SIZE, chid); | ||
106 | result += sprintf(buf + result, "\n"); | ||
107 | |||
102 | return result; | 108 | return result; |
103 | } | 109 | } |
104 | 110 | ||
105 | /* | 111 | /* |
106 | * Store a new CHID | 112 | * Store a new CHID. |
107 | * | ||
108 | * This will (FIXME) trigger many changes. | ||
109 | * | ||
110 | * - Send an all zeros CHID and it will stop the controller | ||
111 | * - Send a non-zero CHID and it will start it | ||
112 | * (unless it was started, it will just change the CHID, | ||
113 | * diconnecting all devices first). | ||
114 | * | 113 | * |
115 | * So first we scan the MMC we are sent and then we act on it. We | 114 | * - Write an all zeros CHID and it will stop the controller |
116 | * read it in the same format as we print it, an ASCII string of 16 | 115 | * - Write a non-zero CHID and it will start it. |
117 | * hex bytes. | ||
118 | * | 116 | * |
119 | * See wusbhc_chid_set() for more info. | 117 | * See wusbhc_chid_set() for more info. |
120 | */ | 118 | */ |
@@ -339,13 +337,15 @@ void wusbhc_giveback_urb(struct wusbhc *wusbhc, struct urb *urb, int status) | |||
339 | { | 337 | { |
340 | struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); | 338 | struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); |
341 | 339 | ||
342 | if (status == 0) { | 340 | if (status == 0 && wusb_dev) { |
343 | wusb_dev->entry_ts = jiffies; | 341 | wusb_dev->entry_ts = jiffies; |
344 | 342 | ||
345 | /* wusbhc_devconnect_acked() can't be called from from | 343 | /* wusbhc_devconnect_acked() can't be called from |
346 | atomic context so defer it to a work queue. */ | 344 | atomic context so defer it to a work queue. */ |
347 | if (!list_empty(&wusb_dev->cack_node)) | 345 | if (!list_empty(&wusb_dev->cack_node)) |
348 | queue_work(wusbd, &wusb_dev->devconnect_acked_work); | 346 | queue_work(wusbd, &wusb_dev->devconnect_acked_work); |
347 | else | ||
348 | wusb_dev_put(wusb_dev); | ||
349 | } | 349 | } |
350 | 350 | ||
351 | usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status); | 351 | usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status); |