U盘无法识别

1. 背景

        多次插拔U盘以后,U盘无响应了。

2. log对比

正常识别:
<6>[ 2519.368698] usb 1-1: new high-speed USB device number 19 using ci_hdrc                    //hub_port_init
<6>[ 2519.531509] usb 1-1: New USB device found, idVendor=0930, idProduct=6544
<6>[ 2519.531527] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
<6>[ 2519.531539] usb 1-1: Product: TransMemory     
<6>[ 2519.531548] usb 1-1: Manufacturer: TOSHIBA 
<6>[ 2519.531558] usb 1-1: SerialNumber: 54B80A3FA798C191C0025649
<6>[ 2519.532558] usb-storage 1-1:1.0: USB Mass Storage device detected
<6>[ 2519.533020] scsi193 : usb-storage 1-1:1.0


无法识别:
<6>[ 2530.498690] usb 1-1: new full-speed USB device number 20 using ci_hdrc							//hub_port_init +4099行
<3>[ 2530.708686] usb 1-1: device no response, 						device descriptor read/64, error -71    // 4178行
<3>[ 2531.028700] usb 1-1: device no response, 						device descriptor read/64, error -71
<6>[ 2531.268687] usb 1-1: new full-speed USB device number 21 using ci_hdrc
<3>[ 2531.488690] usb 1-1: device no response, 						device descriptor read/64, error -71
<3>[ 2531.808701] usb 1-1: device no response, 						device descriptor read/64, error -71
<6>[ 2532.038710] usb 1-1: new full-speed USB device number 22 using ci_hdrc
<3>[ 2532.518671] usb 1-1: device not accepting address 22, error -71
<3>[ 2532.518688] usb 1-1: hub_port_init: Failed to init port, reset PHY.
<6>[ 2532.638694] usb 1-1: new full-speed USB device number 23 using ci_hdrc
<3>[ 2533.118657] usb 1-1: device not accepting address 23, error -71
<3>[ 2533.118674] usb 1-1: hub_port_init: Failed to init port, reset PHY.
<3>[ 2533.118726] hub 1-0:1.0: unable to enumerate USB device on port 1

3. 分析

hub_port_connect_change
	hub_port_init				//无法识别的情况直接就挂在了这里,根本不会执行后面的usb_new_device
		hub_port_reset
			hub_port_wait_reset        //根据portstatus来确认是high-speed还是full-speed usb设备
			r = usb_control_msg        //失败导致打印device no response
			
	usb_new_device				//正常识别情况下打印设备ID的地方
		announce_device

4. 结论

        1. 根据log来看,正常识别的情况是USB port识别为USB2.0,无法识别情况下USB port识别为USB1.1;

        2. 根据源代码来看,出现无法识别是因为hub_port_init失败,细节是“将一个简单的控制消息发送到指定的端点”发生了错误,错误码即-71。

        3. 根据NXP社区信息来看,-71表示I/O错误,似乎是usb 端口不稳定,可能是板子问题或 usb设备问题,例如时钟不稳定、电源或 USB 信号路由不良。

        4. 根据《USB之基础知识》高速设备识别章节可知,高速识别的过程是一个硬件通信过程。

5. 附件

        现在usb全叫usb2.0了 ,一种是usb2.0全速(Full) 相当于以前1.1 传输速度为1.5M/S;另一种是usb2.0高速(high) 就是平时我们说的2.0 传输速度为60M/S。

static int
hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
		int retry_counter)
{
	struct usb_device	*hdev = hub->hdev;
	struct usb_hcd		*hcd = bus_to_hcd(hdev->bus);
	int			retries, operations, retval, i;
	unsigned		delay = HUB_SHORT_RESET_TIME;
	enum usb_device_speed	oldspeed = udev->speed;
	const char		*speed;
	int			devnum = udev->devnum;
	const char		*driver_name;

	/* root hub ports have a slightly longer reset period
	 * (from USB 2.0 spec, section 7.1.7.5)
	 */
	if (!hdev->parent) {
		delay = HUB_ROOT_RESET_TIME;
		if (port1 == hdev->bus->otg_port)
			hdev->bus->b_hnp_enable = 0;
	}

	/* Some low speed devices have problems with the quick delay, so */
	/*  be a bit pessimistic with those devices. RHbug #23670 */
	if (oldspeed == USB_SPEED_LOW)
		delay = HUB_LONG_RESET_TIME;

	mutex_lock(hcd->address0_mutex);

	/* Reset the device; full speed may morph to high speed */
	/* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */
	retval = hub_port_reset(hub, port1, udev, delay, false);
	if (retval < 0)		/* error or disconnect */
		goto fail;
	/* success, speed is known */

	retval = -ENODEV;

	/* Don't allow speed changes at reset, except usb 3.0 to faster */
	if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed &&
	    !(oldspeed == USB_SPEED_SUPER && udev->speed > oldspeed)) {
		dev_dbg(&udev->dev, "device reset changed speed!\n");
		goto fail;
	}
	oldspeed = udev->speed;

	/* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
	 * it's fixed size except for full speed devices.
	 * For Wireless USB devices, ep0 max packet is always 512 (tho
	 * reported as 0xff in the device descriptor). WUSB1.0[4.8.1].
	 */
	switch (udev->speed) {
	case USB_SPEED_SUPER_PLUS:
	case USB_SPEED_SUPER:
	case USB_SPEED_WIRELESS:	/* fixed at 512 */
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
		break;
	case USB_SPEED_HIGH:		/* fixed at 64 */
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
		break;
	case USB_SPEED_FULL:		/* 8, 16, 32, or 64 */
		/* to determine the ep0 maxpacket size, try to read
		 * the device descriptor to get bMaxPacketSize0 and
		 * then correct our initial guess.
		 */
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
		break;
	case USB_SPEED_LOW:		/* fixed at 8 */
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
		break;
	default:
		goto fail;
	}

	if (udev->speed == USB_SPEED_WIRELESS)
		speed = "variable speed Wireless";
	else
		speed = usb_speed_string(udev->speed); //获取字符串full-speed之类的--->


	if (udev->bus->controller->driver)
		driver_name = udev->bus->controller->driver->name;
	else
		driver_name = udev->bus->sysdev->driver->name;

	if (udev->speed < USB_SPEED_SUPER)
 //打印类似:new high-speed USB device number 19 using ci_hdrc
		dev_info(&udev->dev,
				"%s %s USB device number %d using %s\n",
				(udev->config) ? "reset" : "new", speed,
				devnum, driver_name);

		retval = usb_get_device_descriptor(udev, 8);
		if (retval < 8) {
			if (retval != -ENODEV)
				dev_err(&udev->dev,
					"device descriptor read/8, error %d\n",
					retval);
			if (retval >= 0)
				retval = -EMSGSIZE;
		} else {
			retval = 0;
			break;
		}
	}

	usb_detect_quirks(udev);
	return retval;
}

const char *usb_speed_string(enum usb_device_speed speed)
{
	if (speed < 0 || speed >= ARRAY_SIZE(speed_names))
		speed = USB_SPEED_UNKNOWN;
	return speed_names[speed];
}

static const char *const speed_names[] = {
	[USB_SPEED_UNKNOWN] = "UNKNOWN",
	[USB_SPEED_LOW] = "low-speed",
	[USB_SPEED_FULL] = "full-speed",
	[USB_SPEED_HIGH] = "high-speed",
	[USB_SPEED_WIRELESS] = "wireless",
	[USB_SPEED_SUPER] = "super-speed",
	[USB_SPEED_SUPER_PLUS] = "super-speed-plus",
};

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
这一行文本中,`ci_hdrc_usb2_driver_init+0x0/0x10` 表示函数名,`returned 0` 表示函数返回值为 0,`after 396 usecs` 表示函数执行时长为 396 微秒。 因此,可以使用 sed 命令将这一行文本中的信息提取出来,具体命令如下: ```bash echo '[ 7.309563] initcall ci_hdrc_usb2_driver_init+0x0/0x10 returned 0 after 396 usecs' | sed -E 's/.*initcall ([^+]+)\+.+ returned ([0-9]+) after ([0-9]+) usecs/\1 \2 \3/g' ``` 输出结果为: ``` ci_hdrc_usb2_driver_init 0 396 ``` 其中,`ci_hdrc_usb2_driver_init` 是函数名,`0` 是函数返回值,`396` 是函数执行时长,三者之间用空格分隔。 该命令的具体解释如下: - `echo '[ 7.309563] initcall ci_hdrc_usb2_driver_init+0x0/0x10 returned 0 after 396 usecs'`:用于模拟输入原始文本; - `sed -E`:使用 sed 并开启扩展正则表达式模式; - `'s/.*initcall ([^+]+)\+.+ returned ([0-9]+) after ([0-9]+) usecs/\1 \2 \3/g'`:使用正则表达式匹配每行中的函数名、返回值和执行时长,并将它们用空格分隔开来; - `.*initcall`:匹配文本中任意字符,后跟一个空格和 `initcall` 字符串; - `([^+]+)`:匹配函数名部分,中括号表示匹配其中任意一个字符,加号表示匹配前面的字符至少一次,这里的加号需要使用反斜杠转义; - `\+.+ returned `:匹配 `+` 和 `returned` 之间的任意字符; - `([0-9]+)`:匹配返回值部分,中括号表示匹配其中任意一个数字字符,加号表示匹配前面的字符至少一次; - `after `:匹配 `after ` 字符串; - `([0-9]+)`:匹配执行时长部分,同上; - `usecs`:匹配 `usecs` 字符串; - `/\1 \2 \3/g`:替换成三个匹配到的部分,中间用空格分隔,`g` 表示对每行文本都进行替换操作,而不是只替换第一个匹配项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值