Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

На главную -> MyLDP -> Электронные книги по ОС Linux
Цилюрик О.И. Модули ядра Linux
Назад Обслуживание периферийных устройств Вперед

Устройства USB

Схема идентификации устройства парой индексов VendorID — DeviceID, показанная для устройств PCI, оказалась настолько плодотворной, что подобный ей же вариант используется для устройств USB (пара цифр, выводимая после ID):

$ lsusb

	Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 
	Bus 004 Device 003: ID 0461:4d17 Primax Electronics, Ltd Optical Mouse 
	Bus 004 Device 002: ID 0458:0708 KYE Systems Corp. (Mouse Systems) 
	Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 
	Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 
	Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 
	Bus 001 Device 006: ID 08ff:2580 AuthenTec, Inc. AES2501 Fingerprint Sensor 
	Bus 001 Device 003: ID 046d:080f Logitech, Inc. 
	Bus 001 Device 002: ID 0424:2503 Standard Microsystems Corp. USB 2.0 Hub 
	Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub 

Список идентификаторов USB (производитель:устройство) поддерживается в файле с именем usb.ids, в некоторых дистрибутивах он может присутствовать в системе, в других нет, но, в любом случае, лучше воспользоваться самой свежей копией этого файла, например по URL: http://www.linux-usb.org/usb.ids. Для одного из приведенных выше устройств (WEB-камеры), для которого мы будем проводить тест:

	#       List of USB ID's
	# Date:    2011-04-14 20:34:04
	046d  Logitech, Inc.
	...
	        080f  Webcam C120
	...

Подключение (отключение) и регистрацию USB-устройства показывает модуль (архив usb.tgz) lab1_usb.ko (заимствован из [6] при замене, естественно, в коде ID USB устройства на наблюдаемые выше):

lab1_usb.c :

	#include <linux/module.h> 
	#include <linux/init.h> 
	#include <linux/usb.h> 
	#include <linux/slab.h> 

	struct my_usb_info { 
	   int connect_count; 
	}; 
	
	static int my_usb_probe( struct usb_interface *intf, const struct usb_device_id *id ) { 
	   struct my_usb_info *usb_info; 
	   struct usb_device *dev = interface_to_usbdev(intf); 
	   static int my_counter = 0; 
	   printk( KERN_INFO "\nmy_usb_probe\n" ); 
	   printk( KERN_INFO "devnum=%d, speed=%d\n", dev->devnum, (int)dev->speed ); 
	   printk( KERN_INFO "idVendor=0x%hX, idProduct=0x%hX, bcdDevice=0x%hX\n", 
	           dev->descriptor.idVendor, 
	           dev->descriptor.idProduct, dev->descriptor.bcdDevice ); 
	   printk( KERN_INFO "class=0x%hX, subclass=0x%hX\n", 
	           dev->descriptor.bDeviceClass, dev->descriptor.bDeviceSubClass ); 
	   printk( KERN_INFO "protocol=0x%hX, packetsize=%hu\n", 
	           dev->descriptor.bDeviceProtocol, 
	           dev->descriptor.bMaxPacketSize0 ); 
	   printk( KERN_INFO "manufacturer=0x%hX, product=0x%hX, serial=%hu\n", 
	           dev->descriptor.iManufacturer, dev->descriptor.iProduct, 
	           dev->descriptor.iSerialNumber); 
	   usb_info = kmalloc( sizeof( struct my_usb_info ), GFP_KERNEL ); 
	   usb_info->connect_count = my_counter++; 
	   usb_set_intfdata( intf, usb_info ); 
	   printk( KERN_INFO "connect_count=%d\n\n", usb_info->connect_count ); 
	   return 0; 
	} 
	
	static void my_usb_disconnect( struct usb_interface *intf ) { 
	   struct my_usb_info *usb_info; 
	   usb_info = usb_get_intfdata(intf); 
	   printk( KERN_INFO "\nmy_usb_disconnect\n" ); 
	   kfree( usb_info ); 
	} 
	
	static struct usb_device_id my_usb_table[] = { 
	   { USB_DEVICE( 0x046d, 0x080f ) }, // Logitech, Inc. - Webcam C120 
	   {}                                // Null terminator (required) 
	}; 
	
	MODULE_DEVICE_TABLE( usb, my_usb_table ); 
	
	static struct usb_driver my_usb_driver = { 
	   .name = "usb-hotplug", 
	   .probe = my_usb_probe, 
	   .disconnect = my_usb_disconnect, 
	   .id_table = my_usb_table, 
	}; 
	
	static int __init my_init_module( void ) { 
	   int err; 
	   printk( KERN_INFO "Hello USB\n" ); 
	   err = usb_register( &my_usb_driver ); 
	   return err; 
	} 
	
	static void my_cleanup_module( void ) { 
	   printk( KERN_INFO "Goodbye USB\n" ); 
	   usb_deregister( &my_usb_driver ); 
	} 
	
	module_init( my_init_module ); 
	module_exit( my_cleanup_module ); 
	
	MODULE_AUTHOR( "Terry Griffin" ); 
	MODULE_DESCRIPTION( "LDD:1.0 s_28/lab1_usb.c" ); 
	MODULE_LICENSE( "GPL v2" ); 

Работа полученного модуля:

$ sudo insmod lab1_usb.ko.

$ lsmod | grep lab

	lab1_usb                1546  0. 

$ dmesg | tail -n 10

	Hello USB 
	usbcore: registered new interface driver usb-hotplug 

... размыкаем кабель USB-камеры :

$ dmesg | tail -n 3

	Hello USB 
	usbcore: registered new interface driver usb-hotplug 
	usb 1-3: USB disconnect, address 3

... снова подключаем кабель USB-камеры :

$ dmesg | tail -n 10

Hello USB

	usbcore: registered new interface driver usb-hotplug 
	usb 1-3: USB disconnect, address 3
	usb 1-3: new high speed USB device using ehci_hcd and address 7 
	usb 1-3: New USB device found, idVendor=046d, idProduct=080f 
	usb 1-3: New USB device strings: Mfr=0, Product=0, SerialNumber=2 
	usb 1-3: SerialNumber: 1DC23270 
	usb 1-3: configuration #1 chosen from 1 choice 
	uvcvideo: Found UVC 1.00 device <unnamed> (046d:080f) 
	input: UVC Camera (046d:080f) as /devices/pci0000:00/0000:00:1d.7/usb1/1-3/1-3:1.0/input/input13 

$ sudo rmmod lab1_usb

$ dmesg | tail -n 2

	Goodbye USB 
	usbcore: deregistering interface driver usb-hotplug 

Предыдущий раздел: Оглавление Следующий раздел:
DMA   Запуск процессов из ядра