From: Vojtech P. <vo...@us...> - 2002-01-24 19:51:30
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/usb In directory usw-pr-cvs1:/tmp/cvs-serv2610/linux/drivers/usb Modified Files: hid-core.c hid-debug.h hid-input.c hid.h usbkbd.c usbmouse.c wacom.c Log Message: Moving, updating to latest versions. Index: hid-core.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/hid-core.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- hid-core.c 2002/01/22 20:56:42 1.37 +++ hid-core.c 2002/01/24 19:51:26 1.38 @@ -43,7 +43,6 @@ #undef DEBUG_DATA #include <linux/usb.h> -#include "usbpath.h" #include "hid.h" #ifdef CONFIG_USB_HIDDEV @@ -204,27 +203,12 @@ return -1; } -#if 0 /* Old code, could be right in some way, but generates superfluous fields */ - if (HID_MAIN_ITEM_VARIABLE & ~flags) { /* ARRAY */ - if (parser->global.logical_maximum <= parser->global.logical_minimum) { - dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); - return -1; - } - usages = parser->local.usage_index; - /* Hint: we can assume usages < MAX_USAGE here */ - } else { /* VARIABLE */ - usages = parser->global.report_count; - } -#else if (parser->global.logical_maximum <= parser->global.logical_minimum) { dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); return -1; } usages = parser->local.usage_index; - dbg("add_field: usage_index: %d, report_count: %d", parser->global.report_count, parser->local.usage_index); -#endif - offset = report->size; report->size += parser->global.report_size * parser->global.report_count; @@ -338,7 +322,7 @@ return 0; case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: - parser->global.unit_exponent = item_udata(item); + parser->global.unit_exponent = item_sdata(item); return 0; case HID_GLOBAL_ITEM_TAG_UNIT: @@ -761,7 +745,6 @@ #endif } - /* * Analyse a received field, and fetch the data from it. The field * content is stored for next report processing (we do differential @@ -869,13 +852,13 @@ } /* - * Interrupt input handler. + * Input interrupt completion handler. */ -static void hid_irq(struct urb *urb) +static void hid_irq_in(struct urb *urb) { if (urb->status) { - dbg("nonzero status in irq %d", urb->status); + dbg("nonzero status in input irq %d", urb->status); return; } @@ -925,7 +908,8 @@ hid_dump_input(field->usage + offset, value); if (offset >= field->report_count) { - dbg("offset exceeds report_count"); + dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); + hid_dump_field(field, 8); return -1; } if (field->logical_minimum < 0) { @@ -962,6 +946,63 @@ return -1; } +/* + * Find a report with a specified HID usage. + */ + +int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type) +{ + struct hid_report_enum *report_enum = hid->report_enum + type; + struct list_head *list = report_enum->report_list.next; + int i, j; + + while (list != &report_enum->report_list) { + *report = (struct hid_report *) list; + list = list->next; + for (i = 0; i < (*report)->maxfield; i++) { + struct hid_field *field = (*report)->field[i]; + for (j = 0; j < field->maxusage; j++) + if (field->logical == wanted_usage) + return j; + } + } + return -1; +} + +int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field) +{ + int i, j; + + for (i = 0; i < report->maxfield; i++) { + *field = report->field[i]; + for (j = 0; j < (*field)->maxusage; j++) + if ((*field)->usage[j].hid == wanted_usage) + return j; + } + + return -1; +} + +static int hid_submit_out(struct hid_device *hid) +{ + struct hid_report *report; + + report = hid->out[hid->outtail]; + + hid_output_report(report, hid->outbuf); + hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1; + hid->urbout->dev = hid->dev; + + dbg("submitting out urb"); + + if (usb_submit_urb(hid->urbout)) { + err("usb_submit_urb(out) failed"); + return -1; + } + + return 0; +} + static int hid_submit_ctrl(struct hid_device *hid) { struct hid_report *report; @@ -970,22 +1011,22 @@ report = hid->ctrl[hid->ctrltail].report; dir = hid->ctrl[hid->ctrltail].dir; - if (!dir) + if (dir == USB_DIR_OUT) hid_output_report(report, hid->ctrlbuf); - hid->urbctrl.transfer_buffer_length = ((report->size - 1) >> 3) + 1 + ((report->id > 0) && dir); - hid->urbctrl.pipe = dir ? usb_rcvctrlpipe(hid->dev, 0) : usb_sndctrlpipe(hid->dev, 0); - hid->urbctrl.dev = hid->dev; - - hid->dr.wLength = cpu_to_le16(hid->urbctrl.transfer_buffer_length); - hid->dr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; - hid->dr.bRequest = dir ? HID_REQ_GET_REPORT : HID_REQ_SET_REPORT; - hid->dr.wIndex = cpu_to_le16(hid->ifnum); - hid->dr.wValue = ((report->type + 1) << 8) | report->id; + hid->urbctrl->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + ((report->id > 0) && (dir != USB_DIR_OUT)); + hid->urbctrl->pipe = (dir == USB_DIR_OUT) ? usb_sndctrlpipe(hid->dev, 0) : usb_rcvctrlpipe(hid->dev, 0); + hid->urbctrl->dev = hid->dev; + hid->cr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; + hid->cr.bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; + hid->cr.wValue = ((report->type + 1) << 8) | report->id; + hid->cr.wIndex = cpu_to_le16(hid->ifnum); + hid->cr.wLength = cpu_to_le16(hid->urbctrl->transfer_buffer_length); + dbg("submitting ctrl urb"); - if (usb_submit_urb(&hid->urbctrl)) { + if (usb_submit_urb(hid->urbctrl)) { err("usb_submit_urb(ctrl) failed"); return -1; } @@ -993,14 +1034,49 @@ return 0; } +/* + * Output interrupt completion handler. + */ + +static void hid_irq_out(struct urb *urb) +{ + struct hid_device *hid = urb->context; + unsigned long flags; + + if (urb->status) + warn("output irq status %d received", urb->status); + + spin_lock_irqsave(&hid->outlock, flags); + + hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); + + if (hid->outhead != hid->outtail) { + hid_submit_out(hid); + return; + } + + clear_bit(HID_OUT_RUNNING, &hid->iofl); + + spin_unlock_irqrestore(&hid->outlock, flags); + + wake_up(&hid->wait); +} + +/* + * Control pipe completion handler. + */ + static void hid_ctrl(struct urb *urb) { struct hid_device *hid = urb->context; + unsigned long flags; if (urb->status) warn("ctrl urb status %d received", urb->status); - if (hid->ctrl[hid->ctrltail].dir) + spin_lock_irqsave(&hid->ctrllock, flags); + + if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb); hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); @@ -1010,14 +1086,42 @@ return; } + clear_bit(HID_CTRL_RUNNING, &hid->iofl); + + spin_unlock_irqrestore(&hid->ctrllock, flags); + wake_up(&hid->wait); } void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) { int head; + unsigned long flags; + if (dir == USB_DIR_OUT && hid->urbout) { + + spin_lock_irqsave(&hid->outlock, flags); + + if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { + spin_unlock_irqrestore(&hid->outlock, flags); + warn("output queue full"); + return; + } + + hid->out[hid->outhead] = report; + hid->outhead = head; + + if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) + hid_submit_out(hid); + + spin_unlock_irqrestore(&hid->outlock, flags); + return; + } + + spin_lock_irqsave(&hid->ctrllock, flags); + if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { + spin_unlock_irqrestore(&hid->ctrllock, flags); warn("control queue full"); return; } @@ -1026,10 +1130,35 @@ hid->ctrl[hid->ctrlhead].dir = dir; hid->ctrlhead = head; - if (hid->urbctrl.status != -EINPROGRESS) + if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) hid_submit_ctrl(hid); + + spin_unlock_irqrestore(&hid->ctrllock, flags); } +int hid_wait_io(struct hid_device *hid) +{ + DECLARE_WAITQUEUE(wait, current); + int timeout = 10*HZ; + + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&hid->wait, &wait); + + while (timeout && test_bit(HID_CTRL_RUNNING, &hid->iofl) && + test_bit(HID_OUT_RUNNING, &hid->iofl)) + timeout = schedule_timeout(timeout); + + set_current_state(TASK_RUNNING); + remove_wait_queue(&hid->wait, &wait); + + if (!timeout) { + dbg("timeout waiting for ctrl or out queue to clear"); + return -1; + } + + return 0; +} + static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, unsigned char type, void *buf, int size) { @@ -1043,9 +1172,9 @@ if (hid->open++) return 0; - hid->urb.dev = hid->dev; + hid->urbin->dev = hid->dev; - if (usb_submit_urb(&hid->urb)) + if (usb_submit_urb(hid->urbin)) return -EIO; return 0; @@ -1054,7 +1183,7 @@ void hid_close(struct hid_device *hid) { if (!--hid->open) - usb_unlink_urb(&hid->urb); + usb_unlink_urb(hid->urbin); } /* @@ -1063,26 +1192,14 @@ void hid_init_reports(struct hid_device *hid) { - DECLARE_WAITQUEUE(wait, current); struct hid_report_enum *report_enum; struct hid_report *report; struct list_head *list; - int len, timeout = 10*HZ; - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&hid->wait, &wait); - report_enum = hid->report_enum + HID_INPUT_REPORT; list = report_enum->report_list.next; while (list != &report_enum->report_list) { report = (struct hid_report *) list; - len = ((report->size - 1) >> 3) + 1 + report_enum->numbered; - if (len > hid->urb.transfer_buffer_length) { - hid->urb.transfer_buffer_length = len < 32 ? len : 32; - } -#if 0 - usb_set_idle(hid->dev, hid->ifnum, 0, report->id); /*** FIXME mixing sync & async ***/ -#endif hid_submit_report(hid, report, USB_DIR_IN); list = list->next; } @@ -1095,20 +1212,30 @@ list = list->next; } - while (timeout && (hid->ctrlhead != hid->ctrltail)) - timeout = schedule_timeout(timeout); - - set_current_state(TASK_RUNNING); - remove_wait_queue(&hid->wait, &wait); + if (hid_wait_io(hid)) { + warn("timeout initializing reports\n"); + return; + } - if (!timeout) - dbg("timeout waiting for ctrl queue to clear"); + report_enum = hid->report_enum + HID_INPUT_REPORT; + list = report_enum->report_list.next; + while (list != &report_enum->report_list) { + report = (struct hid_report *) list; + usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), + 0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id, + hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); + list = list->next; + } } #define USB_VENDOR_ID_WACOM 0x056a #define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010 #define USB_DEVICE_ID_WACOM_INTUOS 0x0020 +#define USB_VENDOR_ID_GRIFFIN 0x077d +#define USB_DEVICE_ID_POWERMATE 0x0410 +#define USB_DEVICE_ID_SOUNDKNOB 0x04AA + struct hid_blacklist { __u16 idVendor; __u16 idProduct; @@ -1119,6 +1246,8 @@ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2}, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3}, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4}, + { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE }, + { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB }, { 0, 0 } }; @@ -1179,23 +1308,32 @@ if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ continue; - if (!(endpoint->bEndpointAddress & 0x80)) /* Not an input endpoint */ - continue; - - pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - - FILL_INT_URB(&hid->urb, dev, pipe, hid->buffer, 0, hid_irq, hid, endpoint->bInterval); - - break; + if (endpoint->bEndpointAddress & USB_DIR_IN) { + if (hid->urbin) + continue; + if (!(hid->urbin = usb_alloc_urb(0))) + goto fail; + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); + FILL_INT_URB(hid->urbin, dev, pipe, hid->inbuf, 0, hid_irq_in, hid, endpoint->bInterval); + } else { + if (hid->urbout) + continue; + if (!(hid->urbout = usb_alloc_urb(0))) + goto fail; + pipe = usb_sndbulkpipe(dev, endpoint->bEndpointAddress); /* FIXME should we use sndint here? */ + FILL_BULK_URB(hid->urbout, dev, pipe, hid->outbuf, 0, hid_irq_out, hid); + } } - if (n == interface->bNumEndpoints) { - dbg("couldn't find an input interrupt endpoint"); - hid_free_device(hid); - return NULL; + if (!hid->urbin) { + err("couldn't find an input interrupt endpoint"); + goto fail; } init_waitqueue_head(&hid->wait); + + hid->outlock = SPIN_LOCK_UNLOCKED; + hid->ctrllock = SPIN_LOCK_UNLOCKED; hid->version = hdesc->bcdHID; hid->country = hdesc->bCountryCode; @@ -1205,7 +1343,7 @@ hid->name[0] = 0; if (!(buf = kmalloc(64, GFP_KERNEL))) - return NULL; + goto fail; if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) { strcat(hid->name, buf); @@ -1222,9 +1360,19 @@ kfree(buf); - FILL_CONTROL_URB(&hid->urbctrl, dev, 0, (void*) &hid->dr, hid->ctrlbuf, 1, hid_ctrl, hid); + hid->urbctrl = usb_alloc_urb(0); + FILL_CONTROL_URB(hid->urbctrl, dev, 0, (void*) &hid->cr, hid->ctrlbuf, 1, hid_ctrl, hid); return hid; + +fail: + + hid_free_device(hid); + if (hid->urbin) usb_free_urb(hid->urbin); + if (hid->urbout) usb_free_urb(hid->urbout); + if (hid->urbctrl) usb_free_urb(hid->urbctrl); + + return NULL; } static void* hid_probe(struct usb_device *dev, unsigned int ifnum, @@ -1284,7 +1432,14 @@ struct hid_device *hid = ptr; dbg("cleanup called"); - usb_unlink_urb(&hid->urb); + usb_unlink_urb(hid->urbin); + usb_unlink_urb(hid->urbout); + usb_unlink_urb(hid->urbctrl); + + usb_free_urb(hid->urbin); + usb_free_urb(hid->urbctrl); + if (hid->urbout) + usb_free_urb(hid->urbout); if (hid->claimed & HID_CLAIMED_INPUT) hidinput_disconnect(hid); Index: hid-debug.h =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/hid-debug.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- hid-debug.h 2002/01/22 20:56:57 1.9 +++ hid-debug.h 2002/01/24 19:51:26 1.10 @@ -34,6 +34,7 @@ }; static struct hid_usage_entry hid_usage_table[] = { + { 0, 0, "Undefined" }, { 1, 0, "GenericDesktop" }, {0, 0x01, "Pointer"}, {0, 0x02, "Mouse"}, @@ -85,6 +86,7 @@ { 7, 0, "Keyboard" }, { 8, 0, "LED" }, { 9, 0, "Button" }, + { 10, 0, "Ordinal" }, { 12, 0, "Hotkey" }, { 13, 0, "Digitizers" }, {0, 0x01, "Digitizer"}, @@ -110,6 +112,112 @@ {0, 0x45, "Eraser"}, {0, 0x46, "TabletPick"}, { 15, 0, "PhysicalInterfaceDevice" }, + {0, 0x00, "Undefined"}, + {0, 0x01, "Physical_Interface_Device"}, + {0, 0x20, "Normal"}, + {0, 0x21, "Set_Effect_Report"}, + {0, 0x22, "Effect_Block_Index"}, + {0, 0x23, "Parameter_Block_Offset"}, + {0, 0x24, "ROM_Flag"}, + {0, 0x25, "Effect_Type"}, + {0, 0x26, "ET_Constant_Force"}, + {0, 0x27, "ET_Ramp"}, + {0, 0x28, "ET_Custom_Force_Data"}, + {0, 0x30, "ET_Square"}, + {0, 0x31, "ET_Sine"}, + {0, 0x32, "ET_Triangle"}, + {0, 0x33, "ET_Sawtooth_Up"}, + {0, 0x34, "ET_Sawtooth_Down"}, + {0, 0x40, "ET_Spring"}, + {0, 0x41, "ET_Damper"}, + {0, 0x42, "ET_Inertia"}, + {0, 0x43, "ET_Friction"}, + {0, 0x50, "Duration"}, + {0, 0x51, "Sample_Period"}, + {0, 0x52, "Gain"}, + {0, 0x53, "Trigger_Button"}, + {0, 0x54, "Trigger_Repeat_Interval"}, + {0, 0x55, "Axes_Enable"}, + {0, 0x56, "Direction_Enable"}, + {0, 0x57, "Direction"}, + {0, 0x58, "Type_Specific_Block_Offset"}, + {0, 0x59, "Block_Type"}, + {0, 0x5A, "Set_Envelope_Report"}, + {0, 0x5B, "Attack_Level"}, + {0, 0x5C, "Attack_Time"}, + {0, 0x5D, "Fade_Level"}, + {0, 0x5E, "Fade_Time"}, + {0, 0x5F, "Set_Condition_Report"}, + {0, 0x60, "CP_Offset"}, + {0, 0x61, "Positive_Coefficient"}, + {0, 0x62, "Negative_Coefficient"}, + {0, 0x63, "Positive_Saturation"}, + {0, 0x64, "Negative_Saturation"}, + {0, 0x65, "Dead_Band"}, + {0, 0x66, "Download_Force_Sample"}, + {0, 0x67, "Isoch_Custom_Force_Enable"}, + {0, 0x68, "Custom_Force_Data_Report"}, + {0, 0x69, "Custom_Force_Data"}, + {0, 0x6A, "Custom_Force_Vendor_Defined_Data"}, + {0, 0x6B, "Set_Custom_Force_Report"}, + {0, 0x6C, "Custom_Force_Data_Offset"}, + {0, 0x6D, "Sample_Count"}, + {0, 0x6E, "Set_Periodic_Report"}, + {0, 0x6F, "Offset"}, + {0, 0x70, "Magnitude"}, + {0, 0x71, "Phase"}, + {0, 0x72, "Period"}, + {0, 0x73, "Set_Constant_Force_Report"}, + {0, 0x74, "Set_Ramp_Force_Report"}, + {0, 0x75, "Ramp_Start"}, + {0, 0x76, "Ramp_End"}, + {0, 0x77, "Effect_Operation_Report"}, + {0, 0x78, "Effect_Operation"}, + {0, 0x79, "Op_Effect_Start"}, + {0, 0x7A, "Op_Effect_Start_Solo"}, + {0, 0x7B, "Op_Effect_Stop"}, + {0, 0x7C, "Loop_Count"}, + {0, 0x7D, "Device_Gain_Report"}, + {0, 0x7E, "Device_Gain"}, + {0, 0x7F, "PID_Pool_Report"}, + {0, 0x80, "RAM_Pool_Size"}, + {0, 0x81, "ROM_Pool_Size"}, + {0, 0x82, "ROM_Effect_Block_Count"}, + {0, 0x83, "Simultaneous_Effects_Max"}, + {0, 0x84, "Pool_Alignment"}, + {0, 0x85, "PID_Pool_Move_Report"}, + {0, 0x86, "Move_Source"}, + {0, 0x87, "Move_Destination"}, + {0, 0x88, "Move_Length"}, + {0, 0x89, "PID_Block_Load_Report"}, + {0, 0x8B, "Block_Load_Status"}, + {0, 0x8C, "Block_Load_Success"}, + {0, 0x8D, "Block_Load_Full"}, + {0, 0x8E, "Block_Load_Error"}, + {0, 0x8F, "Block_Handle"}, + {0, 0x90, "PID_Block_Free_Report"}, + {0, 0x91, "Type_Specific_Block_Handle"}, + {0, 0x92, "PID_State_Report"}, + {0, 0x94, "Effect_Playing"}, + {0, 0x95, "PID_Device_Control_Report"}, + {0, 0x96, "PID_Device_Control"}, + {0, 0x97, "DC_Enable_Actuators"}, + {0, 0x98, "DC_Disable_Actuators"}, + {0, 0x99, "DC_Stop_All_Effects"}, + {0, 0x9A, "DC_Device_Reset"}, + {0, 0x9B, "DC_Device_Pause"}, + {0, 0x9C, "DC_Device_Continue"}, + {0, 0x9F, "Device_Paused"}, + {0, 0xA0, "Actuators_Enabled"}, + {0, 0xA4, "Safety_Switch"}, + {0, 0xA5, "Actuator_Override_Switch"}, + {0, 0xA6, "Actuator_Power"}, + {0, 0xA7, "Start_Delay"}, + {0, 0xA8, "Parameter_Block_Size"}, + {0, 0xA9, "Device_Managed_Pool"}, + {0, 0xAA, "Shared_Parameter_Blocks"}, + {0, 0xAB, "Create_New_Effect_Report"}, + {0, 0xAC, "RAM_Pool_Available"}, { 0, 0, NULL } }; @@ -174,7 +282,50 @@ tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent); } if (field->unit) { - tab(n); printk("Unit(%u)\n", field->unit); + char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" }; + char *units[5][8] = { + { "None", "None", "None", "None", "None", "None", "None", "None" }, + { "None", "Centimeter", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" }, + { "None", "Radians", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" }, + { "None", "Inch", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" }, + { "None", "Degrees", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" } + }; + + int i; + int sys; + __u32 data = field->unit; + + /* First nibble tells us which system we're in. */ + sys = data & 0xf; + data >>= 4; + + if(sys > 4) { + tab(n); printk("Unit(Invalid)\n"); + } + else { + int earlier_unit = 0; + + tab(n); printk("Unit(%s : ", systems[sys]); + + for (i=1 ; i<sizeof(__u32)*2 ; i++) { + char nibble = data & 0xf; + data >>= 4; + if (nibble != 0) { + if(earlier_unit++ > 0) + printk("*"); + printk("%s", units[sys][i]); + if(nibble != 1) { + /* This is a _signed_ nibble(!) */ + + int val = nibble & 0x7; + if(nibble & 0x08) + val = -((0x7 & ~val) +1); + printk("^%d", val); + } + } + } + printk(")\n"); + } } tab(n); printk("Report Size(%u)\n", field->report_size); tab(n); printk("Report Count(%u)\n", field->report_count); Index: hid-input.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/hid-input.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 Index: hid.h =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/hid.h,v retrieving revision 1.26 retrieving revision 1.27 diff -u -d -r1.26 -r1.27 --- hid.h 2002/01/22 20:57:23 1.26 +++ hid.h 2002/01/24 19:51:26 1.27 @@ -175,6 +175,7 @@ #define HID_UP_KEYBOARD 0x00070000 #define HID_UP_LED 0x00080000 #define HID_UP_BUTTON 0x00090000 +#define HID_UP_ORDINAL 0x000a0000 #define HID_UP_CONSUMER 0x000c0000 #define HID_UP_DIGITIZER 0x000d0000 #define HID_UP_PID 0x000f0000 @@ -215,7 +216,7 @@ __s32 logical_maximum; __s32 physical_minimum; __s32 physical_maximum; - unsigned unit_exponent; + __s32 unit_exponent; unsigned unit; unsigned report_id; unsigned report_size; @@ -272,7 +273,7 @@ __s32 logical_maximum; __s32 physical_minimum; __s32 physical_maximum; - unsigned unit_exponent; + __s32 unit_exponent; unsigned unit; struct hid_report *report; /* associated report */ }; @@ -299,6 +300,7 @@ #define HID_BUFFER_SIZE 32 #define HID_CONTROL_FIFO_SIZE 64 +#define HID_OUTPUT_FIFO_SIZE 64 struct hid_control_fifo { unsigned char dir; @@ -308,6 +310,9 @@ #define HID_CLAIMED_INPUT 1 #define HID_CLAIMED_HIDDEV 2 +#define HID_CTRL_RUNNING 1 +#define HID_OUT_RUNNING 2 + struct hid_device { /* device report descriptor */ __u8 *rdesc; unsigned rsize; @@ -320,15 +325,24 @@ struct usb_device *dev; /* USB device */ int ifnum; /* USB interface number */ - struct urb urb; /* USB URB structure */ - char buffer[HID_BUFFER_SIZE]; /* Rx buffer */ + unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ - struct urb urbctrl; /* Control URB */ - struct usb_ctrlrequest dr; /* Control devrquest struct */ + struct urb *urbin; /* Input URB */ + char inbuf[HID_BUFFER_SIZE]; /* Input buffer */ + + struct urb *urbctrl; /* Control URB */ + struct usb_ctrlrequest cr; /* Control request struct */ struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */ unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */ char ctrlbuf[HID_BUFFER_SIZE]; /* Control buffer */ + spinlock_t ctrllock; /* Control fifo spinlock */ + struct urb *urbout; /* Output URB */ + struct hid_report *out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ + unsigned char outhead, outtail; /* Output pipe fifo head & tail */ + char outbuf[HID_BUFFER_SIZE]; /* Output buffer */ + spinlock_t outlock; /* Output fifo spinlock */ + unsigned claimed; /* Claimed by hidinput, hiddev? */ unsigned quirks; /* Various quirks the device can pull on us */ @@ -381,6 +395,7 @@ #else #define hid_dump_input(a,b) do { } while (0) #define hid_dump_device(c) do { } while (0) +#define hid_dump_field(a,b) do { } while (0) #endif #endif Index: usbkbd.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/usbkbd.c,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- usbkbd.c 2002/01/22 20:59:16 1.30 +++ usbkbd.c 2002/01/24 19:51:26 1.31 @@ -4,8 +4,6 @@ * Copyright (c) 1999-2001 Vojtech Pavlik * * USB HIDBP Keyboard support - * - * Sponsored by SuSE */ /* @@ -24,8 +22,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to <vo...@su...>, or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic + * e-mail - mail your message to <vo...@uc...>, or by paper mail: + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #include <linux/kernel.h> @@ -35,19 +33,17 @@ #include <linux/init.h> #include <linux/usb.h> -#define _HID_BOOT_PROTOCOL -#include "hid.h" - /* * Version Information */ #define DRIVER_VERSION "" -#define DRIVER_AUTHOR "Vojtech Pavlik <vo...@su...>" +#define DRIVER_AUTHOR "Vojtech Pavlik <vo...@uc...>" #define DRIVER_DESC "USB HID Boot Protocol keyboard driver" +#define DRIVER_LICENSE "GPL" -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); -MODULE_LICENSE("GPL"); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE(DRIVER_LICENSE); static unsigned char usb_kbd_keycode[256] = { 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, @@ -74,9 +70,10 @@ unsigned char new[8]; unsigned char old[8]; struct urb irq, led; - struct usb_ctrlrequest dr; + struct usb_ctrlrequest cr; unsigned char leds, newleds; char name[128]; + char phys[64]; int open; }; @@ -181,6 +178,7 @@ struct usb_endpoint_descriptor *endpoint; struct usb_kbd *kbd; int i, pipe, maxp; + char path[64]; char *buf; iface = &dev->actconfig->interface[ifnum]; @@ -195,9 +193,6 @@ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - hid_set_protocol(dev, interface->bInterfaceNumber, 0); - hid_set_idle(dev, interface->bInterfaceNumber, 0, 0); - if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL; memset(kbd, 0, sizeof(struct usb_kbd)); @@ -218,13 +213,17 @@ FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp, usb_kbd_irq, kbd, endpoint->bInterval); - kbd->dr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE; - kbd->dr.bRequest = HID_REQ_SET_REPORT; - kbd->dr.wValue = 0x200; - kbd->dr.wIndex = interface->bInterfaceNumber; - kbd->dr.wLength = 1; + kbd->cr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE; + kbd->cr.bRequest = 0x09; + kbd->cr.wValue = 0x200; + kbd->cr.wIndex = interface->bInterfaceNumber; + kbd->cr.wLength = 1; + + usb_make_path(dev, path, 64); + sprintf(kbd->phys, "%s/input0", path); kbd->dev.name = kbd->name; + kbd->dev.phys = kbd->phys; kbd->dev.idbus = BUS_USB; kbd->dev.idvendor = dev->descriptor.idVendor; kbd->dev.idproduct = dev->descriptor.idProduct; @@ -249,12 +248,11 @@ kfree(buf); FILL_CONTROL_URB(&kbd->led, dev, usb_sndctrlpipe(dev, 0), - (void*) &kbd->dr, &kbd->leds, 1, usb_kbd_led, kbd); + (void*) &kbd->cr, &kbd->leds, 1, usb_kbd_led, kbd); input_register_device(&kbd->dev); - printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n", - kbd->dev.number, kbd->name, dev->bus->busnum, dev->devnum, ifnum); + printk(KERN_INFO "input: %s on %s\n", kbd->name, path); return kbd; } Index: usbmouse.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/usbmouse.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- usbmouse.c 2002/01/22 20:59:30 1.16 +++ usbmouse.c 2002/01/24 19:51:26 1.17 @@ -32,7 +32,6 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> -#include "usbpath.h" /* * Version Information Index: wacom.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/wacom.c,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -r1.29 -r1.30 --- wacom.c 2002/01/22 21:00:01 1.29 +++ wacom.c 2002/01/24 19:51:26 1.30 @@ -65,7 +65,6 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> -#include "usbpath.h" /* * Version Information |