title: Soft Reset USB Device Without Unplugging in Linux
body: <p><strong>Problem:</strong>
  I have USB devices connected to a remote linux machine. I would like to reset them using file descriptors.</p>
  <p>I connect to a port using generic port names in <code>/dev/usbTTYXX</code>. Unfortunately, I quickly found out this was a bad approach as these are generated in order. If I plugged in a tty device first it will generate <code>ttyUSB0</code> and if I plugin a second tty device it will generate <code>TTYUSB1</code> and so on. Unfortunately I have too many different <code>ttyUSB</code> devices and others that break this order. In short its just not user friendly and is a nightmare. I found that it is better to open a port using specific simlink file descriptors in <code>/dev/serial/by-id</code>. This is best preferred since they seem very unique and do not change even after restart, reboot despite order of USB plugged in.</p>
  <p>So I can open a port in a more robust way like so. (I even have a json for this)</p>
  <pre class="lang-c prettyprint-override"><code>// old
  int serial_port = open(&quot;/dev/ttyUSB1&quot;, O_RDWR | O_NOCTTY);
  // new
  int serial_port = open(&quot;/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AC00MET6-if00-port0&quot;, O_RDWR | O_NOCTTY);
  </code></pre>
  <p>No matter how much I reconnect, the USB device will not change (unlike /dev/ttyUSB0). Anyways I found this code that potentially performs a soft-reset to a device so I do not need to replug it in. Here is the <a href="https://www.raspberrypi.org/forums/viewtopic.php?t=49903#p389207" rel="nofollow noreferrer">source</a>:</p>
  <p>If I use this file descriptor <code>/dev/bus/usb/001/010</code> it works. <code>/dev/bus/usb/XXX/YYY</code> where XXX is the bus number (nearly always 001 on the Pi) and YYY is the device number (get both of these from lsusb). Again lsusb also seems to change quite often. (Even more troublesome, I have similar device adapters for the USB which use the same Product and Vendor ID!)</p>
  <p>However it will not work if I use <code>/dev/ttyUSB0</code> or by id with <code>/dev/serial/by-id/</code>. The error I get is <code>Error in ioctl: Inappropriate ioctl for device.</code>.</p>
  <p><strong>Question:</strong> How can I use the ioctrl USBDEVFS_RESET method with the /<code>dev/serial/by-id/</code> file simlinks?</p>
  <pre class="lang-c prettyprint-override"><code>/* usbreset -- send a USB port reset to a USB device */
  
  #include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;sys/ioctl.h&gt;
  
  #include &lt;linux/usbdevice_fs.h&gt;
  
  
  int main(int argc, char **argv)
  {
      const char *filename;
      int fd;
      int rc;
  
      if (argc != 2) {
          fprintf(stderr, &quot;Usage: usbreset device-filename\n&quot;);
          return 1;
      }
      filename = argv[1];
  
      fd = open(filename, O_WRONLY);
      if (fd &lt; 0) {
          perror(&quot;Error opening output file&quot;);
          return 1;
      }
  
      printf(&quot;Resetting USB device %s\n&quot;, filename);
      rc = ioctl(fd, USBDEVFS_RESET, 0);  
      if (rc &lt; 0) {
          perror(&quot;Error in ioctl&quot;);
          return 1;
      }
  
      printf(&quot;Reset successful\n&quot;);
  
      close(fd);
      return 0;
  }
  </code></pre>