How to programatically unplug & replug an USB device in linux?

在linux,更新了usb设备的firmware后,你需要重新插拔一下usb设备来让系统读取到新的usb设备信息。

我们可以通过软件的方式让usb设备reset,实现hot-replug目的,让系统重新读取usb设备信息。

 

有两种方法让内核replug USB设备:

一:使用usbfs系统reset USB设备

先看看源码:

在drivers/usb/core/devio.c里的usbdev_ioctl函数里有

	case USBDEVFS_RESET:
		snoop(&dev->dev, "%s: RESET\n", __func__);
		ret = proc_resetdevice(ps);
		break;

 

proc_resetdevice调用了drivers/usb/core/hub.c的usb_reset_device重置usb设备,使内核replug该usb

 

只需打开usbfs里面对应的usb文件进行ioctl(fd, USBDEVFS_RESET, NULL)即可。

 

二:修改设备驱动,在ioctl里添加USBDEVFS_RESET选项

我在ftdi_sio驱动里,添加

static int ftdi_device_reset(struct usb_serial_port *port)
{
	struct usb_device *dev = port->serial->dev;
	int ret;

	ret = usb_lock_device_for_reset(dev,NULL);
	if (ret == 0) {
		ret = usb_reset_device(dev);
		usb_unlock_device(dev);
	}
	return ret;
}

static int ftdi_ioctl(struct tty_struct *tty, struct file *file,
					unsigned int cmd, unsigned long arg)
{
	struct usb_serial_port *port = tty->driver_data;
	struct ftdi_private *priv = usb_get_serial_port_data(port);

	dbg("%s cmd 0x%04x", __func__, cmd);

	/* Based on code from acm.c and others */
	switch (cmd) {

	/* To support usb_control_msg to ttyUSB */
	case USBDEVFS_CONTROL:
		//dev_printk(KERN_DEBUG, &port->serial->dev->dev, "%s: CONTROL\n", __FUNCTION__);
		return tty_usb_control(port, (void __user *)arg);
		break;

	/* reset after downloading new firmware */
	case USBDEVFS_RESET:
		return ftdi_device_reset(port);
		break;

 

使用该内核,则可以通过设备驱动进行replug该usb设备,很方便。

使用驱动reset设备:

static int usb_device_reset(int fd)
{
  int ret;
	
  #define FTDI_USBDEV_RESET	_IO('U', 20)
  ret = ioctl(fd, FTDI_USBDEV_RESET, NULL);
  if (ret < 0)
    printf("USB device reset: %s\n", strerror(errno));

  return ret;
}

上面的#define FTDI_USBDEV_RESET  _IO('U', 20),其实就是USBDEVFS_RESET

 

我使用修改了的驱动实现,实际效果如下:

root@DLRC:/opt/sniffer/bin#setmoteid_4x -d /dev/ttyUSB0 -w 92
product :HKUST ATC Telos Rev B(9), len:24
old product :HKUST ATC Telos Rev B(9), len:24
new product :   HKUST ATC Telos Rev B(92)
serial save:DS000338, len:8
ftdi_sio 1-1.4.3:1.0: forced unbind
ep93xx-ohci ep93xx-ohci: shutdown urb c563dde0 ep1in-bulk
ftdi_sio 1-1.4.3:1.0: device disconnected
hub 1-1.4:1.0: state 7 ports 4 chg 0000 evt 0008
hub 1-1.4:1.0: state 7 ports 4 chg 0000 evt 0008
usb 1-1.4.3: reset full speed USB device using ep93xx-ohci and address 4
hub 1-1.4:1.0: state 7 ports 4 chg 0000 evt 0008
hub 1-1.4:1.0: state 7 ports 4 chg 0000 evt 0008
usb 1-1.4.3: ep0 maxpacket = 8
usbserial_generic 1-1.4.3:1.0: usb_probe_interface
usbserial_generic 1-1.4.3:1.0: usb_probe_interface - got id
ftdi_sio 1-1.4.3:1.0: usb_probe_interface
ftdi_sio 1-1.4.3:1.0: usb_probe_interface - got id
ftdi_sio 1-1.4.3:1.0: FTDI USB Serial Device converter detected
usb 1-1.4.3: Detected FT232BM
usb 1-1.4.3: FTDI USB Serial Device converter now attached to ttyUSB1
ftdi_sio ttyUSB0: FTDI USB Serial Device converter now disconnected from ttyUSB0


可以看到,reset它,内核就replug该USB。

 


 

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值