|
@@ -521,11 +521,19 @@ static struct wusb_dev *wusbhc_find_dev_by_addr(struct wusbhc *wusbhc, u8 addr)
|
|
|
*
|
|
|
* @wusbhc shall be referenced and unlocked
|
|
|
*/
|
|
|
-static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
|
|
|
+static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, u8 srcaddr)
|
|
|
{
|
|
|
+ struct wusb_dev *wusb_dev;
|
|
|
+
|
|
|
mutex_lock(&wusbhc->mutex);
|
|
|
- wusb_dev->entry_ts = jiffies;
|
|
|
- __wusbhc_keep_alive(wusbhc);
|
|
|
+ wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
|
|
|
+ if (wusb_dev == NULL) {
|
|
|
+ dev_dbg(wusbhc->dev, "ignoring DN_Alive from unconnected device %02x\n",
|
|
|
+ srcaddr);
|
|
|
+ } else {
|
|
|
+ wusb_dev->entry_ts = jiffies;
|
|
|
+ __wusbhc_keep_alive(wusbhc);
|
|
|
+ }
|
|
|
mutex_unlock(&wusbhc->mutex);
|
|
|
}
|
|
|
|
|
@@ -579,14 +587,22 @@ static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc,
|
|
|
*
|
|
|
* @wusbhc shall be referenced and unlocked
|
|
|
*/
|
|
|
-static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
|
|
|
+static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, u8 srcaddr)
|
|
|
{
|
|
|
struct device *dev = wusbhc->dev;
|
|
|
-
|
|
|
- dev_info(dev, "DN DISCONNECT: device 0x%02x going down\n", wusb_dev->addr);
|
|
|
+ struct wusb_dev *wusb_dev;
|
|
|
|
|
|
mutex_lock(&wusbhc->mutex);
|
|
|
- __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, wusb_dev->port_idx));
|
|
|
+ wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
|
|
|
+ if (wusb_dev == NULL) {
|
|
|
+ dev_dbg(dev, "ignoring DN DISCONNECT from unconnected device %02x\n",
|
|
|
+ srcaddr);
|
|
|
+ } else {
|
|
|
+ dev_info(dev, "DN DISCONNECT: device 0x%02x going down\n",
|
|
|
+ wusb_dev->addr);
|
|
|
+ __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc,
|
|
|
+ wusb_dev->port_idx));
|
|
|
+ }
|
|
|
mutex_unlock(&wusbhc->mutex);
|
|
|
}
|
|
|
|
|
@@ -608,30 +624,21 @@ void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr,
|
|
|
struct wusb_dn_hdr *dn_hdr, size_t size)
|
|
|
{
|
|
|
struct device *dev = wusbhc->dev;
|
|
|
- struct wusb_dev *wusb_dev;
|
|
|
|
|
|
if (size < sizeof(struct wusb_dn_hdr)) {
|
|
|
dev_err(dev, "DN data shorter than DN header (%d < %d)\n",
|
|
|
(int)size, (int)sizeof(struct wusb_dn_hdr));
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
- wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
|
|
|
- if (wusb_dev == NULL && dn_hdr->bType != WUSB_DN_CONNECT) {
|
|
|
- dev_dbg(dev, "ignoring DN %d from unconnected device %02x\n",
|
|
|
- dn_hdr->bType, srcaddr);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
switch (dn_hdr->bType) {
|
|
|
case WUSB_DN_CONNECT:
|
|
|
wusbhc_handle_dn_connect(wusbhc, dn_hdr, size);
|
|
|
break;
|
|
|
case WUSB_DN_ALIVE:
|
|
|
- wusbhc_handle_dn_alive(wusbhc, wusb_dev);
|
|
|
+ wusbhc_handle_dn_alive(wusbhc, srcaddr);
|
|
|
break;
|
|
|
case WUSB_DN_DISCONNECT:
|
|
|
- wusbhc_handle_dn_disconnect(wusbhc, wusb_dev);
|
|
|
+ wusbhc_handle_dn_disconnect(wusbhc, srcaddr);
|
|
|
break;
|
|
|
case WUSB_DN_MASAVAILCHANGED:
|
|
|
case WUSB_DN_RWAKE:
|