@ -505,382 +505,3 @@ int usb_kbd_deregister(void)
return 1 ;
# endif
}
#if 0
struct usb_hid_descriptor {
unsigned char bLength ;
unsigned char bDescriptorType ; /* 0x21 for HID */
unsigned short bcdHID ; /* release number */
unsigned char bCountryCode ;
unsigned char bNumDescriptors ;
unsigned char bReportDescriptorType ;
unsigned short wDescriptorLength ;
} __packed ;
/*
* We parse each description item into this structure . Short items data
* values are expanded to 32 - bit signed int , long items contain a pointer
* into the data area .
*/
struct hid_item {
unsigned char format ;
unsigned char size ;
unsigned char type ;
unsigned char tag ;
union {
unsigned char u8 ;
char s8 ;
unsigned short u16 ;
short s16 ;
unsigned long u32 ;
long s32 ;
unsigned char * longdata ;
} data ;
} ;
/*
* HID report item format
*/
# define HID_ITEM_FORMAT_SHORT 0
# define HID_ITEM_FORMAT_LONG 1
/*
* Special tag indicating long items
*/
# define HID_ITEM_TAG_LONG 15
static struct usb_hid_descriptor usb_kbd_hid_desc ;
void usb_kbd_display_hid ( struct usb_hid_descriptor * hid )
{
printf ( " USB_HID_DESC: \n " ) ;
printf ( " bLenght 0x%x \n " , hid - > bLength ) ;
printf ( " bcdHID 0x%x \n " , hid - > bcdHID ) ;
printf ( " bCountryCode %d \n " , hid - > bCountryCode ) ;
printf ( " bNumDescriptors 0x%x \n " , hid - > bNumDescriptors ) ;
printf ( " bReportDescriptorType 0x%x \n " , hid - > bReportDescriptorType ) ;
printf ( " wDescriptorLength 0x%x \n " , hid - > wDescriptorLength ) ;
}
/*
* Fetch a report description item from the data stream . We support long
* items , though they are not used yet .
*/
static int fetch_item ( unsigned char * start , unsigned char * end ,
struct hid_item * item )
{
if ( ( end - start ) > 0 ) {
unsigned char b = * start + + ;
item - > type = ( b > > 2 ) & 3 ;
item - > tag = ( b > > 4 ) & 15 ;
if ( item - > tag = = HID_ITEM_TAG_LONG ) {
item - > format = HID_ITEM_FORMAT_LONG ;
if ( ( end - start ) > = 2 ) {
item - > size = * start + + ;
item - > tag = * start + + ;
if ( ( end - start ) > = item - > size ) {
item - > data . longdata = start ;
start + = item - > size ;
return item - > size ;
}
}
} else {
item - > format = HID_ITEM_FORMAT_SHORT ;
item - > size = b & 3 ;
switch ( item - > size ) {
case 0 :
return item - > size ;
case 1 :
if ( ( end - start ) > = 1 ) {
item - > data . u8 = * start + + ;
return item - > size ;
}
break ;
case 2 :
if ( ( end - start ) > = 2 ) {
item - > data . u16 = le16_to_cpu (
( unsigned short * ) start ) ;
start + = 2 ;
return item - > size ;
}
case 3 :
item - > size + + ;
if ( ( end - start ) > = 4 ) {
item - > data . u32 = le32_to_cpu (
( unsigned long * ) start ) ;
start + = 4 ;
return item - > size ;
}
}
}
}
return - 1 ;
}
/*
* HID report descriptor item type ( prefix bit 2 , 3 )
*/
# define HID_ITEM_TYPE_MAIN 0
# define HID_ITEM_TYPE_GLOBAL 1
# define HID_ITEM_TYPE_LOCAL 2
# define HID_ITEM_TYPE_RESERVED 3
/*
* HID report descriptor main item tags
*/
# define HID_MAIN_ITEM_TAG_INPUT 8
# define HID_MAIN_ITEM_TAG_OUTPUT 9
# define HID_MAIN_ITEM_TAG_FEATURE 11
# define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10
# define HID_MAIN_ITEM_TAG_END_COLLECTION 12
/*
* HID report descriptor main item contents
*/
# define HID_MAIN_ITEM_CONSTANT 0x001
# define HID_MAIN_ITEM_VARIABLE 0x002
# define HID_MAIN_ITEM_RELATIVE 0x004
# define HID_MAIN_ITEM_WRAP 0x008
# define HID_MAIN_ITEM_NONLINEAR 0x010
# define HID_MAIN_ITEM_NO_PREFERRED 0x020
# define HID_MAIN_ITEM_NULL_STATE 0x040
# define HID_MAIN_ITEM_VOLATILE 0x080
# define HID_MAIN_ITEM_BUFFERED_BYTE 0x100
/*
* HID report descriptor collection item types
*/
# define HID_COLLECTION_PHYSICAL 0
# define HID_COLLECTION_APPLICATION 1
# define HID_COLLECTION_LOGICAL 2
/*
* HID report descriptor global item tags
*/
# define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0
# define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1
# define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2
# define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3
# define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4
# define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5
# define HID_GLOBAL_ITEM_TAG_UNIT 6
# define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7
# define HID_GLOBAL_ITEM_TAG_REPORT_ID 8
# define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9
# define HID_GLOBAL_ITEM_TAG_PUSH 10
# define HID_GLOBAL_ITEM_TAG_POP 11
/*
* HID report descriptor local item tags
*/
# define HID_LOCAL_ITEM_TAG_USAGE 0
# define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1
# define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2
# define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3
# define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4
# define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5
# define HID_LOCAL_ITEM_TAG_STRING_INDEX 7
# define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8
# define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9
# define HID_LOCAL_ITEM_TAG_DELIMITER 10
static void usb_kbd_show_item ( struct hid_item * item )
{
switch ( item - > type ) {
case HID_ITEM_TYPE_MAIN :
switch ( item - > tag ) {
case HID_MAIN_ITEM_TAG_INPUT :
printf ( " Main Input " ) ;
break ;
case HID_MAIN_ITEM_TAG_OUTPUT :
printf ( " Main Output " ) ;
break ;
case HID_MAIN_ITEM_TAG_FEATURE :
printf ( " Main Feature " ) ;
break ;
case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION :
printf ( " Main Begin Collection " ) ;
break ;
case HID_MAIN_ITEM_TAG_END_COLLECTION :
printf ( " Main End Collection " ) ;
break ;
default :
printf ( " Main reserved %d " , item - > tag ) ;
break ;
}
break ;
case HID_ITEM_TYPE_GLOBAL :
switch ( item - > tag ) {
case HID_GLOBAL_ITEM_TAG_USAGE_PAGE :
printf ( " - Global Usage Page " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM :
printf ( " - Global Logical Minimum " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM :
printf ( " - Global Logical Maximum " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM :
printf ( " - Global physical Minimum " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM :
printf ( " - Global physical Maximum " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT :
printf ( " - Global Unit Exponent " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_UNIT :
printf ( " - Global Unit " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_REPORT_SIZE :
printf ( " - Global Report Size " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_REPORT_ID :
printf ( " - Global Report ID " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_REPORT_COUNT :
printf ( " - Global Report Count " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_PUSH :
printf ( " - Global Push " ) ;
break ;
case HID_GLOBAL_ITEM_TAG_POP :
printf ( " - Global Pop " ) ;
break ;
default :
printf ( " - Global reserved %d " , item - > tag ) ;
break ;
}
break ;
case HID_ITEM_TYPE_LOCAL :
switch ( item - > tag ) {
case HID_LOCAL_ITEM_TAG_USAGE :
printf ( " -- Local Usage " ) ;
break ;
case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM :
printf ( " -- Local Usage Minimum " ) ;
break ;
case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM :
printf ( " -- Local Usage Maximum " ) ;
break ;
case HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX :
printf ( " -- Local Designator Index " ) ;
break ;
case HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM :
printf ( " -- Local Designator Minimum " ) ;
break ;
case HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM :
printf ( " -- Local Designator Maximum " ) ;
break ;
case HID_LOCAL_ITEM_TAG_STRING_INDEX :
printf ( " -- Local String Index " ) ;
break ;
case HID_LOCAL_ITEM_TAG_STRING_MINIMUM :
printf ( " -- Local String Minimum " ) ;
break ;
case HID_LOCAL_ITEM_TAG_STRING_MAXIMUM :
printf ( " -- Local String Maximum " ) ;
break ;
case HID_LOCAL_ITEM_TAG_DELIMITER :
printf ( " -- Local Delimiter " ) ;
break ;
default :
printf ( " -- Local reserved %d " , item - > tag ) ;
break ;
}
break ;
default :
printf ( " --- reserved %d " , item - > type ) ;
break ;
}
switch ( item - > size ) {
case 1 :
printf ( " %d " , item - > data . u8 ) ;
break ;
case 2 :
printf ( " %d " , item - > data . u16 ) ;
break ;
case 4 :
printf ( " %ld " , item - > data . u32 ) ;
break ;
}
printf ( " \n " ) ;
}
static int usb_kbd_get_hid_desc ( struct usb_device * dev )
{
unsigned char buffer [ 256 ] ;
struct usb_descriptor_header * head ;
struct usb_config_descriptor * config ;
int index , len , i ;
unsigned char * start , * end ;
struct hid_item item ;
if ( usb_get_configuration_no ( dev , & buffer [ 0 ] , 0 ) = = - 1 )
return - 1 ;
head = ( struct usb_descriptor_header * ) & buffer [ 0 ] ;
if ( head - > bDescriptorType ! = USB_DT_CONFIG ) {
printf ( " ERROR: NOT USB_CONFIG_DESC %x \n " ,
head - > bDescriptorType ) ;
return - 1 ;
}
index = head - > bLength ;
config = ( struct usb_config_descriptor * ) & buffer [ 0 ] ;
len = le16_to_cpu ( config - > wTotalLength ) ;
/*
* Ok the first entry must be a configuration entry ,
* now process the others
*/
head = ( struct usb_descriptor_header * ) & buffer [ index ] ;
while ( index + 1 < len ) {
if ( head - > bDescriptorType = = USB_DT_HID ) {
printf ( " HID desc found \n " ) ;
memcpy ( & usb_kbd_hid_desc , & buffer [ index ] ,
buffer [ index ] ) ;
le16_to_cpus ( & usb_kbd_hid_desc . bcdHID ) ;
le16_to_cpus ( & usb_kbd_hid_desc . wDescriptorLength ) ;
usb_kbd_display_hid ( & usb_kbd_hid_desc ) ;
len = 0 ;
break ;
}
index + = head - > bLength ;
head = ( struct usb_descriptor_header * ) & buffer [ index ] ;
}
if ( len > 0 )
return - 1 ;
len = usb_kbd_hid_desc . wDescriptorLength ;
index = usb_get_class_descriptor ( dev , 0 , USB_DT_REPORT , 0 , & buffer [ 0 ] ,
len ) ;
if ( index < 0 ) {
printf ( " reading report descriptor failed \n " ) ;
return - 1 ;
}
printf ( " report descriptor (size %u, read %d) \n " , len , index ) ;
start = & buffer [ 0 ] ;
end = & buffer [ len ] ;
i = 0 ;
do {
index = fetch_item ( start , end , & item ) ;
i + = index ;
i + + ;
if ( index > = 0 )
usb_kbd_show_item ( & item ) ;
start + = index ;
start + + ;
} while ( index > = 0 ) ;
}
# endif