The USB Serial Driver Layer, Part II
In the first part of this article [LJ, February 2003], I introduced the USB serial layer and the basics of how to register a driver with the layer. This article explains some of the details about how data flows through the layer and how USB serial devices show up in sysfs.
In Part I of this article, I briefly mentioned the generic USB driver in the context of getting a USB device to communicate through it easily, with no custom kernel programming. Unfortunately, I didn't explain exactly how to do this, and many people wrote in with questions.
To create a USB device that works with the generic USB serial driver, all that is needed is two bulk USB endpoints on the device, one IN and one OUT. The generic USB serial driver will bind those two endpoints together into a single tty device that can be read from and written to from user space. For example, a device with the endpoints as described by /proc/bus/usb/devices (Figure 1) shows up as a single port device and produces the following kernel message when plugged in:
Generic converter detected
Generic converter now attached to ttyUSB0
(or usb/tts/0 for devfs)
Then any user can send data to the device through the /dev/ttyUSB0 node.

Figure 1. A Sample /proc/bus/usb/devices Entry
If a device has more than one bulk IN and bulk OUT pair, multiple ports are assigned to the device. For example, a device with the endpoints as described by /proc/bus/usb/devices (Figure 2) shows up as a two-port device and produces the following kernel messages when plugged in:
Generic converter detected
Generic converter now attached to ttyUSB0
(or usb/tts/0 for devfs)
Generic converter now attached to ttyUSB1
(or usb/tts/1 for devfs)
For this device, both /dev/ttyUSB0 and /dev/ttyUSB1 can be used to communicate.
The order of the endpoints is not important, so all of the IN endpoints could be first, followed by the OUT endpoints (unlike the previous examples that alternate). The USB serial core will take all of the IN and OUT endpoints and pair them up in the order they are seen. It also will assign an interrupt endpoint to a bulk pair, if one is present, but the interrupt endpoint will not be used by the generic driver; it can be used only by a USB serial driver within the kernel.
To get the generic USB serial driver to bind to the device, the USB vendor and product IDs need to be specified as a module parameter when the usbserial module is loaded. For example, to bind to the previously described device with a vendor ID of ffff and product ID of fff8, use the following command:
modprobe usbserial vendor=0xffff product=0xfff8
If the user cannot be expected to load the usbserial module with the specific device ID, or if more than one device ID should be used by the generic USB serial driver, a very tiny driver can be written. An example of this is shown in Listing 1. In this driver, no callback functions are specified, only the product and vendor IDs of the devices that should be controlled. This is shown in the declaration of the struct usb_serial_device_type:
static struct usb_serial_device_type tiny_device = {
.owner = THIS_MODULE,
.name = "Tiny USB serial",
.short_name = "tiny",
.id_table = id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
.num_bulk_out = NUM_DONT_CARE,
.num_ports = 1,
};
Specific vendor and product IDs should be listed in the id_table
pointer:
static struct usb_device_id id_table [] = {
{ USB_DEVICE(MY_PRODUCT_ID, MY_DEVICE_ID1) },
{ USB_DEVICE(MY_PRODUCT_ID, MY_DEVICE_ID2) },
{ USB_DEVICE(MY_PRODUCT_ID, MY_DEVICE_ID3) },
{ } /* Terminating entry */
};
Listing 1. The Tiny Tiny USB Serial Driver
In all, this driver contains only two functions, which are two and three lines long, and three variable definitions. With it, all of the generic USB serial driver functionality will occur for the specified devices. The driver automatically will be loaded for the device when it is plugged in to the system, which is also a nice feature. This has to be one of the smallest working Linux kernel drivers possible. Compile it with:
echo "obj-m := tiny_tiny_usbserial.o" > Makefile make -C <path/to/kernel/src> SUBDIRS=$PWD modules
The Windows operating system also supports this kind of device interface through the Windows USB OPOS serial driver, which will create virtual “COM” ports for the device. This allows hardware vendors to create USB devices that do not require any custom driver development for both Linux and Windows machines, which can be highly desirable.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- A Topic for Discussion - Open Source Feature-Richness?
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Validate an E-Mail Address with PHP, the Right Way
- RSS Feeds
- Readers' Choice Awards
- Tech Tip: Really Simple HTTP Server with Python
- BASH script to log IPs on public web server
2 hours 12 min ago - DynDNS
5 hours 47 min ago - Reply to comment | Linux Journal
6 hours 20 min ago - All the articles you talked
8 hours 43 min ago - All the articles you talked
8 hours 46 min ago - All the articles you talked
8 hours 48 min ago - myip
13 hours 13 min ago - Keeping track of IP address
15 hours 4 min ago - Roll your own dynamic dns
20 hours 17 min ago - Please correct the URL for Salt Stack's web site
23 hours 28 min ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?





Comments
Re: The USB Serial Driver Layer, Part II
thank you
Some doubts
Hi,
When data is received by the USB serial driver for a specific port, it should place the data into the specific tty structure assigned to that port's flip buffer:
for (i = 0; i < data_size; ++i) {
if (tty->flip.count >= TTY_FLIPBUF_SIZE)
tty_flip_buffer_push(tty);
tty_insert_flip_char(tty, data[i], 0);
}
tty_flip_buffer_push(tty);
u told that data received is stored in flip buffer is the data is read by usb serial or serial core or others .
please reply regarding the read of data from device to the PC. when the the read function called by user on serial which function executes in USB