Commit d96835d3 authored by Vojtech Pavlik's avatar Vojtech Pavlik

[PATCH] Update of USB input drivers to the latest versions

Now that the input core changes have made it into 2.5 I can finally
update the USB input drivers to their latest versions.

Here is a patch that does that.

In detail:

	HID driver:
		Fix a bug in descriptor parsing (array/variable),
			namely visible with Logitech new joysticks and mice
		Fix bugs in logical/physical min/max parsing
		Fix bugs in exponent parsing
		Remove workaround for low-speed devices with >8 byte
			reports, fix this in a correct way (bigger irq
			request)
		Untangle some code (fetc_item())
		Implement asynchronous input/output/feature report
			reading and writing
		Implement (hopefully) proper locking in the above
		Implement support for devices with an output endpoint
		Add some support functions for force feedback support
			currently in development
		Add entries to the debug dump code, including FF and
			exponents
		Add more mappings into the hid-input interface
		Cleanups here and there

	usbkbd driver:

		Make LED URBS use GFP_ATOMIC, they'll be called from a
			completion handler
		Remove dependency on hid.h

	usbmouse driver:

		Just conversion to the new input core, minor cleanups

	wacom driver:

		Just conversion to the new input core.
parent 61251b87
This diff is collapsed.
/*
* $Id: hid-debug.h,v 1.3 2001/05/10 15:56:07 vojtech Exp $
* $Id: hid-debug.h,v 1.8 2001/09/25 09:37:57 vojtech Exp $
*
* (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de>
* (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz>
* (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
*
* Some debug stuff for the HID parser.
*
* Sponsored by SuSE
*/
/*
......@@ -25,8 +23,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 <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
struct hid_usage_entry {
......@@ -36,6 +34,7 @@ struct hid_usage_entry {
};
static struct hid_usage_entry hid_usage_table[] = {
{ 0, 0, "Undefined" },
{ 1, 0, "GenericDesktop" },
{0, 0x01, "Pointer"},
{0, 0x02, "Mouse"},
......@@ -87,6 +86,7 @@ static struct hid_usage_entry hid_usage_table[] = {
{ 7, 0, "Keyboard" },
{ 8, 0, "LED" },
{ 9, 0, "Button" },
{ 10, 0, "Ordinal" },
{ 12, 0, "Hotkey" },
{ 13, 0, "Digitizers" },
{0, 0x01, "Digitizer"},
......@@ -112,6 +112,112 @@ static struct hid_usage_entry hid_usage_table[] = {
{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 }
};
......@@ -176,7 +282,50 @@ static void hid_dump_field(struct hid_field *field, int n) {
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);
......
/*
* $Id: hid-input.c,v 1.5 2001/05/23 09:25:02 vojtech Exp $
* $Id: hid-input.c,v 1.18 2001/11/07 09:01:18 vojtech Exp $
*
* Copyright (c) 2000-2001 Vojtech Pavlik
*
* USB HID to Linux Input mapping module
*
* Sponsored by SuSE
* USB HID to Linux Input mapping
*/
/*
......@@ -24,13 +22,12 @@
* 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 <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/usb.h>
......@@ -61,12 +58,13 @@ static unsigned char hid_keyboard[256] = {
static struct {
__s32 x;
__s32 y;
} hid_hat_to_axis[] = {{0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
} hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
static void hidinput_configure_usage(struct hid_device *device, struct hid_field *field, struct hid_usage *usage)
{
struct input_dev *input = &device->input;
int max;
int is_abs = 0;
unsigned long *bit;
switch (usage->hid & HID_USAGE_PAGE) {
......@@ -198,6 +196,7 @@ static void hidinput_configure_usage(struct hid_device *device, struct hid_field
case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */
set_bit(EV_REP, input->evbit);
switch (usage->hid & HID_USAGE) {
case 0x000: usage->code = 0; break;
case 0x034: usage->code = KEY_SLEEP; break;
......@@ -205,14 +204,21 @@ static void hidinput_configure_usage(struct hid_device *device, struct hid_field
case 0x08a: usage->code = KEY_WWW; break;
case 0x095: usage->code = KEY_HELP; break;
case 0x0b0: usage->code = KEY_PLAY; break;
case 0x0b1: usage->code = KEY_PAUSE; break;
case 0x0b2: usage->code = KEY_RECORD; break;
case 0x0b3: usage->code = KEY_FASTFORWARD; break;
case 0x0b4: usage->code = KEY_REWIND; break;
case 0x0b5: usage->code = KEY_NEXTSONG; break;
case 0x0b6: usage->code = KEY_PREVIOUSSONG; break;
case 0x0b7: usage->code = KEY_STOPCD; break;
case 0x0b8: usage->code = KEY_EJECTCD; break;
case 0x0cd: usage->code = KEY_PLAYPAUSE; break;
case 0x0e0: is_abs = 1;
usage->code = ABS_VOLUME;
break;
case 0x0e2: usage->code = KEY_MUTE; break;
case 0x0e5: usage->code = KEY_BASSBOOST; break;
case 0x0e9: usage->code = KEY_VOLUMEUP; break;
case 0x0ea: usage->code = KEY_VOLUMEDOWN; break;
......@@ -220,7 +226,6 @@ static void hidinput_configure_usage(struct hid_device *device, struct hid_field
case 0x18a: usage->code = KEY_MAIL; break;
case 0x192: usage->code = KEY_CALC; break;
case 0x194: usage->code = KEY_FILE; break;
case 0x21a: usage->code = KEY_UNDO; break;
case 0x21b: usage->code = KEY_COPY; break;
case 0x21c: usage->code = KEY_CUT; break;
......@@ -234,6 +239,34 @@ static void hidinput_configure_usage(struct hid_device *device, struct hid_field
case 0x227: usage->code = KEY_REFRESH; break;
case 0x22a: usage->code = KEY_BOOKMARKS; break;
default: usage->code = KEY_UNKNOWN; break;
}
if (is_abs) {
usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;
} else {
usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
}
break;
case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */
set_bit(EV_REP, input->evbit);
switch (usage->hid & HID_USAGE) {
case 0x021: usage->code = KEY_PRINT; break;
case 0x070: usage->code = KEY_HP; break;
case 0x071: usage->code = KEY_CAMERA; break;
case 0x072: usage->code = KEY_SOUND; break;
case 0x073: usage->code = KEY_QUESTION; break;
case 0x080: usage->code = KEY_EMAIL; break;
case 0x081: usage->code = KEY_CHAT; break;
case 0x082: usage->code = KEY_SEARCH; break;
case 0x083: usage->code = KEY_CONNECT; break;
case 0x084: usage->code = KEY_FINANCE; break;
case 0x085: usage->code = KEY_SPORT; break;
case 0x086: usage->code = KEY_SHOP; break;
default: usage->code = KEY_UNKNOWN; break;
}
......@@ -353,7 +386,7 @@ static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsign
}
hid_set_field(field, offset, value);
hid_write_report(hid, field->report);
hid_submit_report(hid, field->report, USB_DIR_OUT);
return 0;
}
......@@ -397,6 +430,8 @@ int hidinput_connect(struct hid_device *hid)
hid->input.close = hidinput_close;
hid->input.name = hid->name;
hid->input.phys = hid->phys;
hid->input.uniq = hid->uniq;
hid->input.idbus = BUS_USB;
hid->input.idvendor = dev->descriptor.idVendor;
hid->input.idproduct = dev->descriptor.idProduct;
......
......@@ -2,12 +2,10 @@
#define __HID_H
/*
* $Id: hid.h,v 1.10 2001/05/10 15:56:07 vojtech Exp $
* $Id: hid.h,v 1.24 2001/12/27 10:37:41 vojtech Exp $
*
* Copyright (c) 1999 Andreas Gal
* Copyright (c) 2000-2001 Vojtech Pavlik
*
* Sponsored by SuSE
*/
/*
......@@ -26,13 +24,24 @@
* 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 <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/list.h>
/*
* USB HID (Human Interface Device) interface class code
*/
#define USB_INTERFACE_CLASS_HID 3
/*
* HID class requests
*/
#define HID_REQ_GET_REPORT 0x01
#define HID_REQ_GET_IDLE 0x02
#define HID_REQ_GET_PROTOCOL 0x03
......@@ -43,85 +52,11 @@
/*
* HID class descriptor types
*/
#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
/*
* Utilities for class control messaging
*/
static inline int
hid_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id)
{
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
(duration << 8) | report_id, ifnum, NULL, 0,
HZ * USB_CTRL_SET_TIMEOUT);
}
static inline int
hid_get_protocol(struct usb_device *dev, int ifnum)
{
unsigned char type;
int ret;
if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
HID_REQ_GET_PROTOCOL,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0, ifnum, &type, 1,
HZ * USB_CTRL_GET_TIMEOUT)) < 0)
return ret;
return type;
}
static inline int
hid_set_protocol(struct usb_device *dev, int ifnum, int protocol)
{
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
HID_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
protocol, ifnum, NULL, 0,
HZ * USB_CTRL_SET_TIMEOUT);
}
static inline int
hid_get_report(struct usb_device *dev, int ifnum, unsigned char type,
unsigned char id, void *buf, int size)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
HID_REQ_GET_REPORT,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
(type << 8) + id, ifnum, buf, size,
HZ * USB_CTRL_GET_TIMEOUT);
}
static inline int
hid_set_report(struct usb_device *dev, int ifnum, unsigned char type,
unsigned char id, void *buf, int size)
{
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
HID_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
(type << 8) + id, ifnum, buf, size, HZ);
// FIXME USB_CTRL_SET_TIMEOUT
}
/*
* "Boot Protocol" keyboard/mouse drivers use don't use all of HID;
* they're a lot smaller but can't support all the device features.
*/
#ifndef _HID_BOOT_PROTOCOL
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/list.h>
/*
* USB HID (Human Interface Device) interface class code
*/
#define USB_INTERFACE_CLASS_HID 3
/*
* We parse each description item into this structure. Short items data
* values are expanded to 32-bit signed int, long items contain a pointer
......@@ -240,9 +175,11 @@ struct hid_item {
#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
#define HID_UP_HPVENDOR 0xff7f0000
#define HID_USAGE 0x0000ffff
......@@ -279,7 +216,7 @@ struct hid_global {
__s32 logical_maximum;
__s32 physical_minimum;
__s32 physical_maximum;
unsigned unit_exponent;
__s32 unit_exponent;
unsigned unit;
unsigned report_id;
unsigned report_size;
......@@ -336,7 +273,7 @@ struct hid_field {
__s32 logical_maximum;
__s32 physical_minimum;
__s32 physical_maximum;
unsigned unit_exponent;
__s32 unit_exponent;
unsigned unit;
struct hid_report *report; /* associated report */
};
......@@ -350,8 +287,6 @@ struct hid_report {
struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
unsigned maxfield; /* maximum valid field index */
unsigned size; /* size of the report (bits) */
unsigned idx; /* where we're in data */
unsigned char *data; /* data for multi-packet reports */
struct hid_device *device; /* associated device */
};
......@@ -364,16 +299,20 @@ struct hid_report_enum {
#define HID_REPORT_TYPES 3
#define HID_BUFFER_SIZE 32
#define HID_CONTROL_FIFO_SIZE 8
#define HID_CONTROL_FIFO_SIZE 64
#define HID_OUTPUT_FIFO_SIZE 64
struct hid_control_fifo {
struct usb_ctrlrequest dr;
char buffer[HID_BUFFER_SIZE];
unsigned char dir;
struct hid_report *report;
};
#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;
......@@ -386,12 +325,23 @@ struct hid_device { /* device report descriptor */
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 *urbin; /* Input URB */
char inbuf[HID_BUFFER_SIZE]; /* Input buffer */
struct urb urbout; /* Output URB */
struct hid_control_fifo out[HID_CONTROL_FIFO_SIZE]; /* Transmit buffer */
unsigned char outhead, outtail; /* Tx buffer head & tail */
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 */
......@@ -400,8 +350,12 @@ struct hid_device { /* device report descriptor */
void *hiddev; /* The hiddev structure */
int minor; /* Hiddev minor number */
wait_queue_head_t wait; /* For sleeping */
int open; /* is the device open by anyone? */
char name[128]; /* Device name */
char phys[64]; /* Device physical location */
char uniq[64]; /* Device unique identifier (serial #) */
};
#define HID_GLOBAL_STACK_SIZE 4
......@@ -441,19 +395,18 @@ void hidinput_disconnect(struct hid_device *);
#else
#define hid_dump_input(a,b) do { } while (0)
#define hid_dump_device(c) do { } while (0)
#endif /* DEBUG */
#define hid_dump_field(a,b) do { } while (0)
#endif
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || ( a == 0x000c0001))
#endif
/* Applications from HID Usage Tables 4/8/99 Version 1.1 */
/* We ignore a few input applications that are not widely used */
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || ( a == 0x00010080) || ( a == 0x000c0001))
int hid_open(struct hid_device *);
void hid_close(struct hid_device *);
int hid_find_field(struct hid_device *, unsigned int, unsigned int, struct hid_field **);
int hid_set_field(struct hid_field *, unsigned, __s32);
void hid_write_report(struct hid_device *, struct hid_report *);
void hid_read_report(struct hid_device *, struct hid_report *);
void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir);
void hid_init_reports(struct hid_device *hid);
#endif /* !_HID_BOOT_PROTOCOL */
#endif /* !__HID_H */
......@@ -400,7 +400,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file,
if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
return -EINVAL;
hid_read_report(hid, report);
hid_submit_report(hid, report, USB_DIR_IN);
return 0;
......@@ -414,7 +414,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file,
if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
return -EINVAL;
hid_write_report(hid, report);
hid_submit_report(hid, report, USB_DIR_OUT);
return 0;
......
/*
* $Id: usbkbd.c,v 1.20 2001/04/26 08:34:49 vojtech Exp $
* $Id: usbkbd.c,v 1.27 2001/12/27 10:37:41 vojtech Exp $
*
* 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 <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@ucw.cz>, 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 <vojtech@suse.cz>"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
#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 @@ struct usb_kbd {
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;
};
......@@ -129,7 +126,7 @@ int usb_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, i
kbd->leds = kbd->newleds;
kbd->led->dev = kbd->usbdev;
if (usb_submit_urb(kbd->led, GFP_KERNEL))
if (usb_submit_urb(kbd->led, GFP_ATOMIC))
err("usb_submit_urb(leds) failed");
return 0;
......@@ -147,7 +144,7 @@ static void usb_kbd_led(struct urb *urb)
kbd->leds = kbd->newleds;
kbd->led->dev = kbd->usbdev;
if (usb_submit_urb(kbd->led, GFP_KERNEL))
if (usb_submit_urb(kbd->led, GFP_ATOMIC))
err("usb_submit_urb(leds) failed");
}
......@@ -181,6 +178,7 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
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 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
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));
......@@ -230,13 +225,17 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
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;
......@@ -261,12 +260,11 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
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;
}
......
/*
* $Id: usbmouse.c,v 1.6 2000/08/14 21:05:26 vojtech Exp $
* $Id: usbmouse.c,v 1.15 2001/12/27 10:37:41 vojtech Exp $
*
* Copyright (c) 1999-2000 Vojtech Pavlik
* Copyright (c) 1999-2001 Vojtech Pavlik
*
* USB HIDBP Mouse 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 <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>
......@@ -35,23 +33,22 @@
#include <linux/init.h>
#include <linux/usb.h>
#define _HID_BOOT_PROTOCOL
#include "hid.h"
/*
* Version Information
*/
#define DRIVER_VERSION "v1.6"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
#define DRIVER_DESC "USB HID Boot Protocol mouse 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);
struct usb_mouse {
signed char data[8];
char name[128];
char phys[64];
struct usb_device *usbdev;
struct input_dev dev;
struct urb *irq;
......@@ -107,6 +104,7 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
struct usb_endpoint_descriptor *endpoint;
struct usb_mouse *mouse;
int pipe, maxp;
char path[64];
char *buf;
iface = &dev->actconfig->interface[ifnum];
......@@ -121,8 +119,6 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
hid_set_idle(dev, interface->bInterfaceNumber, 0, 0);
if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL;
memset(mouse, 0, sizeof(struct usb_mouse));
......@@ -144,7 +140,11 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
mouse->dev.open = usb_mouse_open;
mouse->dev.close = usb_mouse_close;
usb_make_path(dev, path, 64);
sprintf(mouse->phys, "%s/input0", path);
mouse->dev.name = mouse->name;
mouse->dev.phys = mouse->phys;
mouse->dev.idbus = BUS_USB;
mouse->dev.idvendor = dev->descriptor.idVendor;
mouse->dev.idproduct = dev->descriptor.idProduct;
......@@ -173,8 +173,7 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
input_register_device(&mouse->dev);
printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
mouse->dev.number, mouse->name, dev->bus->busnum, dev->devnum, ifnum);
printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
return mouse;
}
......
/*
* $Id: wacom.c,v 1.22 2001/04/26 11:26:09 vojtech Exp $
* $Id: wacom.c,v 1.28 2001/09/25 10:12:07 vojtech Exp $
*
* Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz>
* Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
* Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
* Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
* Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org>
......@@ -11,8 +11,6 @@
*
* USB Wacom Graphire and Wacom Intuos tablet support
*
* Sponsored by SuSE
*
* ChangeLog:
* v0.1 (vp) - Initial release
* v0.2 (aba) - Support for all buttons / combinations
......@@ -57,8 +55,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 <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>
......@@ -72,12 +70,13 @@
* Version Information
*/
#define DRIVER_VERSION "v1.21"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet 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);
#define USB_VENDOR_ID_WACOM 0x056a
......@@ -106,6 +105,7 @@ struct wacom {
int open;
int x, y;
__u32 serial[2];
char phys[32];
};
static void wacom_pl_irq(struct urb *urb)
......@@ -354,6 +354,7 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struc
{
struct usb_endpoint_descriptor *endpoint;
struct wacom *wacom;
char path[64];
if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) return NULL;
memset(wacom, 0, sizeof(struct wacom));
......@@ -394,7 +395,11 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struc
wacom->dev.open = wacom_open;
wacom->dev.close = wacom_close;
usb_make_path(dev, path, 64);
sprintf(wacom->phys, "%s/input0", path);
wacom->dev.name = wacom->features->name;
wacom->dev.phys = wacom->phys;
wacom->dev.idbus = BUS_USB;
wacom->dev.idvendor = dev->descriptor.idVendor;
wacom->dev.idproduct = dev->descriptor.idProduct;
......@@ -408,8 +413,7 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struc
input_register_device(&wacom->dev);
printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
wacom->dev.number, wacom->features->name, dev->bus->busnum, dev->devnum, ifnum);
printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path);
return wacom;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment