소스 검색

USB: Handle auto-transition from hot to warm reset.

USB 3.0 hubs and roothubs will automatically transition a failed hot
reset to a warm (BH) reset.  In that case, the warm reset change bit
will be set, and the link state change bit may also be set.  Change
hub_port_finish_reset to unconditionally clear those change bits for USB
3.0 hubs.  If these bits are not cleared, we may lose port change events
from the roothub.

This commit should be backported to kernels as old as 3.2, that contain
the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine
warm reset logic".

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: stable@vger.kernel.org
Sarah Sharp 12 년 전
부모
커밋
1c7439c61f
1개의 변경된 파일3개의 추가작업 그리고 3개의 파일을 삭제
  1. 3 3
      drivers/usb/core/hub.c

+ 3 - 3
drivers/usb/core/hub.c

@@ -2580,16 +2580,16 @@ static void hub_port_finish_reset(struct usb_hub *hub, int port1,
 		clear_port_feature(hub->hdev,
 		clear_port_feature(hub->hdev,
 				port1, USB_PORT_FEAT_C_RESET);
 				port1, USB_PORT_FEAT_C_RESET);
 		/* FIXME need disconnect() for NOTATTACHED device */
 		/* FIXME need disconnect() for NOTATTACHED device */
-		if (warm) {
+		if (hub_is_superspeed(hub->hdev)) {
 			clear_port_feature(hub->hdev, port1,
 			clear_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_C_BH_PORT_RESET);
 					USB_PORT_FEAT_C_BH_PORT_RESET);
 			clear_port_feature(hub->hdev, port1,
 			clear_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_C_PORT_LINK_STATE);
 					USB_PORT_FEAT_C_PORT_LINK_STATE);
-		} else {
+		}
+		if (!warm)
 			usb_set_device_state(udev, *status
 			usb_set_device_state(udev, *status
 					? USB_STATE_NOTATTACHED
 					? USB_STATE_NOTATTACHED
 					: USB_STATE_DEFAULT);
 					: USB_STATE_DEFAULT);
-		}
 		break;
 		break;
 	}
 	}
 }
 }