title: How to read/write to an USB storage device with a linux driver?
body: <p>During the attempt to write my own simple usb driver for an usb-flash-drive, I got stuck reading the data that I wrote to the device.
  So, my first question is:</p>
  
  <p><strong>How is the transfer and the storage on a device going on?</strong> (in detail)</p>
  
  <p>I know I have to perform the following steps:</p>
  
  <ul>
  <li>Create an urb (USB request block)</li>
  <li>Allocate a DMA buffer</li>
  <li>Transfer the data from the user-space into the DMA buffer</li>
  <li>Send the data through a pipe to the device</li>
  </ul>
  
  <p>I couldn't find any documentation on how a device handles this data.</p>
  
  <p><strong>Is this even possible to write such a driver, or would it be necessary to disassemble the usb device, to send special commands?</strong></p>
  
  <p>The code I have written looks something like the following and is from the ldd3 and "<a href="http://lxr.free-electrons.com/source/drivers/usb/usb-skeleton.c" rel="nofollow">http://lxr.free-electrons.com/source/drivers/usb/usb-skeleton.c</a>". It only shows a shortened version of the important functions. </p>
  
  <p>After loading the driver into the kernel, I can write to the device without any error, but if I read, an <em>EPIPE</em> error occurs. Ldd3 mentions that the <em>usb_clear_halt()</em> could solve this problem, but it doesn't.</p>
  
  <pre><code>// This function is called when the device is plugged in
  static int my_driver_probe(struct usb_interface* interface, const struct usb_device_id* id)
  {
      struct usb_skel* dev = NULL;
      struct usb_device* udev = interface_to_usbdev(interface);
      struct usb_host_interface* iface_desc;
      struct usb_endpoint_descriptor* endpoint;
      int retval = -ENODEV;
      int i = 0;
      size_t buffer_size;
  
      dev = kzalloc(sizeof(struct usb_skel), GFP_KERNEL);
  
      // Check vendor and product id
      // … 
  
      dev-&gt;udev = udev;
      dev-&gt;interface = interface;
  
      // Set up the endpoint information
      iface_desc = interface-&gt;cur_altsetting;
      for(i=0; i &lt; iface_desc-&gt;desc.bNumEndpoints; ++i) {
          endpoint = &amp;iface_desc-&gt;endpoint[i].desc;
  
          if(!dev-&gt;bulk_in_endpointAddr &amp;&amp; usb_endpoint_is_bulk_in(endpoint)) {
              buffer_size = endpoint-&gt;wMaxPacketSize;
              dev-&gt;bulk_in_size = buffer_size;
              dev-&gt;bulk_in_endpointAddr = endpoint-&gt;bEndpointAddress;
              dev-&gt;bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
              if(!dev-&gt;bulk_in_buffer) {
                  printk("Could not allocate bulk_in_buffer\n");
                  goto error;
              }
              dev-&gt;bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
          }
          if(!dev-&gt;bulk_out_endpointAddr &amp;&amp; usb_endpoint_is_bulk_out(endpoint))
              dev-&gt;bulk_out_endpointAddr = endpoint-&gt;bEndpointAddress;
      }
      // Check that the endpoints are set
      // … 
  
      // Save our data pointer in this interface device
      usb_set_intfdata(interface, dev);
  
      // Register the device
      retval = usb_register_dev(interface, &amp;class_descr);
      return retval;
  }
  
  // Is called when another program writes into /dev/my_usb_driver
  static ssize_t my_driver_write( struct file* file, const char __user* user_buffer, size_t count, loff_t* offs)
  {
      struct usb_skel* dev = file-&gt;private_data;
      struct urb* urb = NULL;
      char* buf = NULL;
      int retval = 0;
      size_t writesize = min(count, (size_t)MAX_TRANSFER);
  
      // Create a urb, and a buffer for it, and copy the data to the urb
      urb = usb_alloc_urb(0, GFP_KERNEL);
  
      // Creates a DMA buffer
      buf = usb_alloc_coherent(dev-&gt;udev, writesize, GFP_KERNEL, &amp;urb-&gt;transfer_dma);
  
      // The data that is passed to the driver should be copied into the DMA buffer
      copy_from_user(buf, user_buffer, writesize;
  
      // Initialize the urb proberly
      usb_fill_bulk_urb(urb, dev-&gt;udev, 
                    usb_sndbulkpipe(dev-&gt;udev, dev-&gt;bulk_out_endpointAddr),
                    buf, writesize, (void*)my_write_bulk_callback, dev);
  
      // Send the data out the bulk port
      urb-&gt;transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
  
      usb_submit_urb(urb, GFP_KERNEL);
  
      return writesize; 
  }
  
  // Is called when another program reads from /dev/my_usb_driver
  static ssize_t my_driver_read( struct file *file, char* buffer, size_t count, loff_t* offs) 
  {
      struct usb_skel* dev = file-&gt;private_data;
      int retval = 0;
  
      // Check that we have data to read
      // … 
  
      usb_fill_bulk_urb(dev-&gt;bulk_in_urb, dev-&gt;udev, 
                    usb_rcvbulkpipe(dev-&gt;udev, dev-&gt;bulk_in_endpointAddr),
                    dev-&gt;bulk_in_buffer, 
                    min(dev-&gt;bulk_in_size, count), read_bulk_callback, dev);  
  
      retval = usb_submit_urb(dev-&gt;bulk_in_urb, GFP_KERNEL);
  
      // If the read was succesful, copy the data to user space
      copy_to_user(buffer, dev-&gt;bulk_in_buffer, count);
  
      return retval;
  }
  </code></pre>