Writing a Real Driver—In User Space

Now you can control USB hardware without touching the kernel and even make your driver run on BSD-based OSes with no code changes. Greg shows a working example for using the cross-platform USB library, libusb.


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

How to create device entry under /dev in rootfs

Santhosh's picture


I am facing a issue, while creating /dev entry for LCD backlight driver.

I am using following functions for doing the same.

1) alloc_chrdev_region(&bl->bdev, 0, 1, BIHP_BL_DEVICE_NAME);
2) cdev_init(&bl->cdev, &bl_fops);
3) cdev_add(&bl->cdev, bl->bdev, 1);

Compilation is done properly, If I check /dev entry for backlight there it is showing nothing.

Please let me know, Am I doing any thing wrong?

Kind Regards,
Santhosh Reddy.P

Check /proc/devices

Mitch Frazier's picture

The device name (BIHP_BL_DEVICE_NAME) you specify in alloc_chrdev_region() puts an entry in /proc/devices not /dev. You create the /dev file with mknod.

Mitch Frazier is an Associate Editor for Linux Journal.

/proc/bus/usb deprecated

joshperry's picture

Just FYI /proc/bus/usb has been deprecated for a while and in fact is no longer mounted by default on recent Linux distros. The new location is /dev/bus/usb.


Anonymous's picture

I've been trying to figure out how to do an isochronous read but I'm not having any luck. Could you please outline the sequence of steps to accomplish this. I'm using libusb_fill_iso_transfer () followed by libusb_submit_transfer () but this hangs up inside libusb. I'm suspicious that libusb is incomplete since I don't see any way of specifying the interval.
Also, I need to get at the manufacturers name string, but all I can find is an index (iManufacturer) in the device descriptor. There should be an access function.

So far I've been able to open this device, detach the kernel driver and claim the interface.

The device has a vendorId=18f5 and a productId=1000 (yes, it's in the Linux list). The device contains 2 joysticks and 16 switches (it's not a gaming device), I need to read the raw data so that I can extract the individual components. I have the memory map. Using usbviewer I found one endpoint at 0x81, the transfer size is 12 bytes and the interval is 5ms.

access data from USB using c++

amit's picture

how can i access data from USB using c++ code, libusb1.0, in linux.

Some questions.

Kyuhyong's picture

Hello, it's a very nice posting and great help for newbie like me.
I'm trying to implement a usb driver that enables a programmer can write a program to communicate with a usb device. But your advice seems not working for me because our device has API that communicate with the device and I just want the api can initialize the device and programmers don't have to care about it.
Could you give me any advice on that?

Also, I'm confused about the header file you included in the program. It has usb.h instead of libusb.h. is it something different from the libusb.h or you just wrote another header that refers libusb.h?



Anonymous's picture

Hi ,

This is a very interesting article . Is the documentation for using USBFS IOCTL's documented .

I wanted to issue basic USB String Descriptor to a device .

Help is appreciated


What are the usb_control_msg values?

Reid's picture

Hi Greg -

Thanks for the great article. It's been a big help in writing a program to talk to a little communications board that I'm working with.

I have a question about the usb_control_msg() function, and I can't find any documentation on it (no man page, even on the Google?).

What are requesttype, request, value, and index for, exactly? Your program has requesttype 0x000000c8 (not sure where this is defined/how you chose it), request 0x00000012 (again, not sure how you decided this was the option to use), value (0x02 * 0x100) + 0x0a, index 0xff & (~color). It seems a little odd to me, wouldn't the request type/etc simply be part of the usb packet header and the data would be which pins you're setting? Probably my device is a little more complicated :).

I've been using SnoopyPro to sniff my device (i have a program for windows that interfaces with it correctly) and all the communication with the device is using Function "BULK_OR_INTERRUPT_TRANSFER" (0x09), so I'm guessing this would be my request_type? or my request? My device receives data via the buffer variable, so buffer and length are a no brainer (I know what these values need to be), I'm just not sure about these header-y things. If you have any idea or know a good place for documentation, toss it my way.

Thanks a ton,

yeah! What are the usb_control_msg values?

Roberto's picture

Somebody can you tell us?

According SnoopyPro for my device i got something like this:

URB Header (length: 80)
SequenceNumber: 10
Function: 001b (CLASS_INTERFACE)
PipeHandle: 00000000
0000: 22 01 00 03 00 00 00 00
bmRequestType: 22
DIR: Host-To-Device
TYPE: Class
bRequest: 01
No TransferBuffer

I guess that bmRequestType:22 is the 2nd parameter, bRequest:01 is the 3rd. But, what about the 'value' and 'index' parameters?

If you read the line-> 0000: 22 01 00 03 00 00 00 00 it's the command sent to the device .. but how can i put this into the usb_control_msg function?


PS: I don't speak english ... sorry

Errors while compilling

Felipe's picture

Anybody could help me?
I found some errors wihle I tried do compile this example:

g++ -c -o usb.o usb.cc
usb.cc: In function ‘void change_color(usb_dev_handle*, unsigned char)’:
usb.cc:24: error: ‘usb_control_msg’ was not declared in this scope
usb.cc: In function ‘usb_device* device_init()’:
usb.cc:30: error: ‘usb_init’ was not declared in this scope
usb.cc:31: error: ‘usb_find_busses’ was not declared in this scope
usb.cc:32: error: ‘usb_find_devices’ was not declared in this scope
usb.cc:33: error: ‘usb_busses’ was not declared in this scope
usb.cc:35: error: invalid use of undefined type ‘struct usb_bus’
usb.cc:28: error: forward declaration of ‘struct usb_bus’
usb.cc:36: error: invalid use of undefined type ‘struct usb_bus’
usb.cc:28: error: forward declaration of ‘struct usb_bus’
usb.cc:38: error: invalid use of undefined type ‘struct usb_device’
usb.cc:26: error: forward declaration of ‘struct usb_device’
usb.cc:39: error: invalid use of undefined type ‘struct usb_device’
usb.cc:26: error: forward declaration of ‘struct usb_device’
usb.cc:41: error: invalid use of undefined type ‘struct usb_device’
usb.cc:26: error: forward declaration of ‘struct usb_device’
usb.cc: In function ‘int main(int, char**)’:
usb.cc:60: error: ‘usb_open’ was not declared in this scope
usb.cc:63: error: expected primary-expression before ‘goto’
usb.cc:89: error: ‘usb_close’ was not declared in this scope

expected primary-expression before "goto"

Daniel's picture

Same problem when I try to use goto in the place like these
if(goto location);
i!=j?goto location:exit;
If you know the solution or why is this happening plz mail me.


Errors while compilling

Dusan Sukovic's picture

Hi Felipe,

Try this:
locate libusb

gcc -o driver driver.c -L/usr/local/lib -lusb

It compiles without problems on OpenBSD 4.1, just remember to force library path to libusb to compile.


Anonymous's picture

I wanted to write just a simple driver for my usb-mass-storage (memory stick).
All I want to do is to flash (On/Off) the led on the device. It is only one led, I changed the LED_VENDOR_ID and LED_PRODUCT_ID Everything works fine, except that this usb_control_msg() doesnt work for this device :(!
Can someone help me with this? All I want is to switch this Led On and Off! Nothing more :).
Do I have to use another function? Is there a function that can manage to do this(put this only Led on)?
I hope u can help me with this.

Thank you

Little mistake in the code

acs's picture

In the program code appears:

if (usb_handle == NULL) {
goto exit;

I think this is a block that can be deleted because the error check is also done in the next block.

¡Nice article!

Bad code...

Tim's picture

Hmm, goto's are bad anywhere.

Also doesn't your control message write 8 bytes to a random location (dummy isn't initialised)?

And you don't use usb_claim_interface() anywhere. The doc's say this "Must be called!" I'm not entirely sure what an interface is yet though. libusb has terrible documentation. It is also the best example of why C++ is better than C that I've ever seen.

Re: Writing a Real Driver

Anonymous's picture


I just want to ask for some links to more information about USB in general, how to implement USB in Self build devices,
An overview, how USB (and pehaps also the serial and parallel interface) are implemented in Gnu/Linux and also BSD-Unix.

I'm an Engineer and it was easy to send some bytes to a device in the Dos Area - continued in Win9x. How can I do it - as easy as possible in Linux, especialy if new computers only have USB - this is the Future if we believe Intel

D. Schneider

Re: Writing a Real Driver

Anonymous's picture


this is in your example code:
usb_handle = usb_open(usb_dev);
if (usb_handle == NULL) {
goto exit;

usb_handle = usb_open(usb_dev);
if (usb_handle == NULL) {
"Not able to claim the USB device
goto exit;

Sorry for the request but the libusb developer manual say to call usb_init() and usb_claim_device() (for claim), before any operation with USB device...

There are step by step example to respect correct order?


ioctl for massive storage device

Jing's picture


I want to access the massive storage device (memory stick) using ioctl instead of libusb. Can you recommend a reference for this purpose?

I tried to do the work but was not successful. The sequence of actions I did is as following:

/*open the device*/
fd = open(file, O_RDWR);

/*reset the device*/
fd = open(file, O_RDWR);

/*configure the device*/
ioctl(fd, USBDEVFS_SETCONFIGURATION, &configuration);

/*claim the interface*/
ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);

/*read data via the bulk endpoint*/
ioctl(fd, USBDEVFS_BULK, &bulk);

All steps successed until it failed at the last step.