Commit 4916b3a5 authored by Jiri Kosina's avatar Jiri Kosina Committed by Greg Kroah-Hartman

[PATCH] Generic HID layer - USB API

- 'dev' in struct hid_device changed from struct usb_device to
  struct device and fixed all the users
- renamed functions which are part of USB HID API from 'hid_*' to
  'usbhid_*'
- force feedback initialization moved from common part into USB-specific
  driver
- added usbhid.h header for USB HID API users
- removed USB-specific fields from struct hid_device and moved them
  to new usbhid_device, which is pointed to by hid_device->driver_data
- fixed all USB users to use this new structure
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 229695e5
...@@ -798,8 +798,7 @@ int hidinput_connect(struct hid_device *hid) ...@@ -798,8 +798,7 @@ int hidinput_connect(struct hid_device *hid)
input_dev->id.vendor = hid->vendor; input_dev->id.vendor = hid->vendor;
input_dev->id.product = hid->product; input_dev->id.product = hid->product;
input_dev->id.version = hid->version; input_dev->id.version = hid->version;
input_dev->cdev.dev = &hid->intf->dev; input_dev->cdev.dev = hid->dev;
hidinput->input = input_dev; hidinput->input = input_dev;
list_add_tail(&hidinput->list, &hid->inputs); list_add_tail(&hidinput->list, &hid->inputs);
} }
...@@ -821,13 +820,8 @@ int hidinput_connect(struct hid_device *hid) ...@@ -821,13 +820,8 @@ int hidinput_connect(struct hid_device *hid)
} }
} }
/* This only gets called when we are a single-input (most of the if (hidinput)
* time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is
* only useful in this case, and not for multi-input quirks. */
if (hidinput) {
hid_ff_init(hid);
input_register_device(hidinput->input); input_register_device(hidinput->input);
}
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -70,8 +70,8 @@ static struct hid_ff_initializer inits[] = { ...@@ -70,8 +70,8 @@ static struct hid_ff_initializer inits[] = {
int hid_ff_init(struct hid_device* hid) int hid_ff_init(struct hid_device* hid)
{ {
struct hid_ff_initializer *init; struct hid_ff_initializer *init;
int vendor = le16_to_cpu(hid->dev->descriptor.idVendor); int vendor = le16_to_cpu(to_usb_device(hid->dev)->descriptor.idVendor);
int product = le16_to_cpu(hid->dev->descriptor.idProduct); int product = le16_to_cpu(to_usb_device(hid->dev)->descriptor.idProduct);
for (init = inits; init->idVendor; init++) for (init = inits; init->idVendor; init++)
if (init->idVendor == vendor && init->idProduct == product) if (init->idVendor == vendor && init->idProduct == product)
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/hid.h> #include <linux/hid.h>
#include "usbhid.h"
struct device_type { struct device_type {
u16 idVendor; u16 idVendor;
...@@ -75,7 +76,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef ...@@ -75,7 +76,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
report->field[0]->value[2] = x; report->field[0]->value[2] = x;
report->field[0]->value[3] = y; report->field[0]->value[3] = y;
dbg("(x, y)=(%04x, %04x)", x, y); dbg("(x, y)=(%04x, %04x)", x, y);
hid_submit_report(hid, report, USB_DIR_OUT); usbhid_submit_report(hid, report, USB_DIR_OUT);
break; break;
case FF_RUMBLE: case FF_RUMBLE:
...@@ -90,7 +91,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef ...@@ -90,7 +91,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
report->field[0]->value[2] = left; report->field[0]->value[2] = left;
report->field[0]->value[3] = right; report->field[0]->value[3] = right;
dbg("(left, right)=(%04x, %04x)", left, right); dbg("(left, right)=(%04x, %04x)", left, right);
hid_submit_report(hid, report, USB_DIR_OUT); usbhid_submit_report(hid, report, USB_DIR_OUT);
break; break;
} }
return 0; return 0;
......
...@@ -262,7 +262,7 @@ static void pidff_set_envelope_report(struct pidff_device *pidff, ...@@ -262,7 +262,7 @@ static void pidff_set_envelope_report(struct pidff_device *pidff,
debug("attack %u => %d", envelope->attack_level, debug("attack %u => %d", envelope->attack_level,
pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); pidff->set_envelope[PID_ATTACK_LEVEL].value[0]);
hid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE], usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
USB_DIR_OUT); USB_DIR_OUT);
} }
...@@ -289,7 +289,7 @@ static void pidff_set_constant_force_report(struct pidff_device *pidff, ...@@ -289,7 +289,7 @@ static void pidff_set_constant_force_report(struct pidff_device *pidff,
pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE], pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE],
effect->u.constant.level); effect->u.constant.level);
hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT], usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT],
USB_DIR_OUT); USB_DIR_OUT);
} }
...@@ -324,7 +324,7 @@ static void pidff_set_effect_report(struct pidff_device *pidff, ...@@ -324,7 +324,7 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
pidff->effect_direction); pidff->effect_direction);
pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay; pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
USB_DIR_OUT); USB_DIR_OUT);
} }
...@@ -356,7 +356,7 @@ static void pidff_set_periodic_report(struct pidff_device *pidff, ...@@ -356,7 +356,7 @@ static void pidff_set_periodic_report(struct pidff_device *pidff,
pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase); pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period; pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
hid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC], usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC],
USB_DIR_OUT); USB_DIR_OUT);
} }
...@@ -398,8 +398,8 @@ static void pidff_set_condition_report(struct pidff_device *pidff, ...@@ -398,8 +398,8 @@ static void pidff_set_condition_report(struct pidff_device *pidff,
effect->u.condition[i].left_saturation); effect->u.condition[i].left_saturation);
pidff_set(&pidff->set_condition[PID_DEAD_BAND], pidff_set(&pidff->set_condition[PID_DEAD_BAND],
effect->u.condition[i].deadband); effect->u.condition[i].deadband);
hid_wait_io(pidff->hid); usbhid_wait_io(pidff->hid);
hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION], usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION],
USB_DIR_OUT); USB_DIR_OUT);
} }
} }
...@@ -440,7 +440,7 @@ static void pidff_set_ramp_force_report(struct pidff_device *pidff, ...@@ -440,7 +440,7 @@ static void pidff_set_ramp_force_report(struct pidff_device *pidff,
effect->u.ramp.start_level); effect->u.ramp.start_level);
pidff_set_signed(&pidff->set_ramp[PID_RAMP_END], pidff_set_signed(&pidff->set_ramp[PID_RAMP_END],
effect->u.ramp.end_level); effect->u.ramp.end_level);
hid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP], usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP],
USB_DIR_OUT); USB_DIR_OUT);
} }
...@@ -465,19 +465,19 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) ...@@ -465,19 +465,19 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
int j; int j;
pidff->create_new_effect_type->value[0] = efnum; pidff->create_new_effect_type->value[0] = efnum;
hid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT], usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
USB_DIR_OUT); USB_DIR_OUT);
debug("create_new_effect sent, type: %d", efnum); debug("create_new_effect sent, type: %d", efnum);
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
pidff->block_load_status->value[0] = 0; pidff->block_load_status->value[0] = 0;
hid_wait_io(pidff->hid); usbhid_wait_io(pidff->hid);
for (j = 0; j < 60; j++) { for (j = 0; j < 60; j++) {
debug("pid_block_load requested"); debug("pid_block_load requested");
hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD], usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD],
USB_DIR_IN); USB_DIR_IN);
hid_wait_io(pidff->hid); usbhid_wait_io(pidff->hid);
if (pidff->block_load_status->value[0] == if (pidff->block_load_status->value[0] ==
pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) { pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) {
debug("device reported free memory: %d bytes", debug("device reported free memory: %d bytes",
...@@ -513,8 +513,8 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n) ...@@ -513,8 +513,8 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
pidff->effect_operation[PID_LOOP_COUNT].value[0] = n; pidff->effect_operation[PID_LOOP_COUNT].value[0] = n;
} }
hid_wait_io(pidff->hid); usbhid_wait_io(pidff->hid);
hid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION], usbhid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
USB_DIR_OUT); USB_DIR_OUT);
} }
...@@ -536,7 +536,7 @@ static int pidff_playback(struct input_dev *dev, int effect_id, int value) ...@@ -536,7 +536,7 @@ static int pidff_playback(struct input_dev *dev, int effect_id, int value)
static void pidff_erase_pid(struct pidff_device *pidff, int pid_id) static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
{ {
pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id; pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE], usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE],
USB_DIR_OUT); USB_DIR_OUT);
} }
...@@ -716,7 +716,7 @@ static void pidff_set_gain(struct input_dev *dev, u16 gain) ...@@ -716,7 +716,7 @@ static void pidff_set_gain(struct input_dev *dev, u16 gain)
struct pidff_device *pidff = dev->ff->private; struct pidff_device *pidff = dev->ff->private;
pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain); pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain);
hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
USB_DIR_OUT); USB_DIR_OUT);
} }
...@@ -741,7 +741,7 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude) ...@@ -741,7 +741,7 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
pidff_set(&pidff->set_effect[PID_GAIN], magnitude); pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
pidff->set_effect[PID_START_DELAY].value[0] = 0; pidff->set_effect[PID_START_DELAY].value[0] = 0;
hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
USB_DIR_OUT); USB_DIR_OUT);
} }
...@@ -1165,19 +1165,19 @@ static void pidff_reset(struct pidff_device *pidff) ...@@ -1165,19 +1165,19 @@ static void pidff_reset(struct pidff_device *pidff)
pidff->device_control->value[0] = pidff->control_id[PID_RESET]; pidff->device_control->value[0] = pidff->control_id[PID_RESET];
/* We reset twice as sometimes hid_wait_io isn't waiting long enough */ /* We reset twice as sometimes hid_wait_io isn't waiting long enough */
hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
hid_wait_io(hid); usbhid_wait_io(hid);
hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
hid_wait_io(hid); usbhid_wait_io(hid);
pidff->device_control->value[0] = pidff->device_control->value[0] =
pidff->control_id[PID_ENABLE_ACTUATORS]; pidff->control_id[PID_ENABLE_ACTUATORS];
hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
hid_wait_io(hid); usbhid_wait_io(hid);
/* pool report is sometimes messed up, refetch it */ /* pool report is sometimes messed up, refetch it */
hid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN); usbhid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN);
hid_wait_io(hid); usbhid_wait_io(hid);
if (pidff->pool[PID_SIMULTANEOUS_MAX].value) { if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0]; int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0];
...@@ -1189,9 +1189,9 @@ static void pidff_reset(struct pidff_device *pidff) ...@@ -1189,9 +1189,9 @@ static void pidff_reset(struct pidff_device *pidff)
break; break;
} }
debug("pid_pool requested again"); debug("pid_pool requested again");
hid_submit_report(hid, pidff->reports[PID_POOL], usbhid_submit_report(hid, pidff->reports[PID_POOL],
USB_DIR_IN); USB_DIR_IN);
hid_wait_io(hid); usbhid_wait_io(hid);
} }
} }
} }
...@@ -1277,7 +1277,7 @@ int hid_pidff_init(struct hid_device *hid) ...@@ -1277,7 +1277,7 @@ int hid_pidff_init(struct hid_device *hid)
if (test_bit(FF_GAIN, dev->ffbit)) { if (test_bit(FF_GAIN, dev->ffbit)) {
pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff); pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
USB_DIR_OUT); USB_DIR_OUT);
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/hid.h> #include <linux/hid.h>
#include "usbhid.h"
/* Usages for thrustmaster devices I know about */ /* Usages for thrustmaster devices I know about */
#define THRUSTMASTER_USAGE_RUMBLE_LR (HID_UP_GENDESK | 0xbb) #define THRUSTMASTER_USAGE_RUMBLE_LR (HID_UP_GENDESK | 0xbb)
...@@ -70,7 +71,7 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef ...@@ -70,7 +71,7 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef
tmff->rumble->value[0] = left; tmff->rumble->value[0] = left;
tmff->rumble->value[1] = right; tmff->rumble->value[1] = right;
dbg("(left,right)=(%08x, %08x)", left, right); dbg("(left,right)=(%08x, %08x)", left, right);
hid_submit_report(hid, tmff->report, USB_DIR_OUT); usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
return 0; return 0;
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/hid.h> #include <linux/hid.h>
#include "usbhid.h"
struct zpff_device { struct zpff_device {
struct hid_report *report; struct hid_report *report;
...@@ -56,7 +57,7 @@ static int hid_zpff_play(struct input_dev *dev, void *data, ...@@ -56,7 +57,7 @@ static int hid_zpff_play(struct input_dev *dev, void *data,
zpff->report->field[2]->value[0] = left; zpff->report->field[2]->value[0] = left;
zpff->report->field[3]->value[0] = right; zpff->report->field[3]->value[0] = right;
debug("running with 0x%02x 0x%02x", left, right); debug("running with 0x%02x 0x%02x", left, right);
hid_submit_report(hid, zpff->report, USB_DIR_OUT); usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
return 0; return 0;
} }
...@@ -101,7 +102,7 @@ int hid_zpff_init(struct hid_device *hid) ...@@ -101,7 +102,7 @@ int hid_zpff_init(struct hid_device *hid)
zpff->report->field[1]->value[0] = 0x02; zpff->report->field[1]->value[0] = 0x02;
zpff->report->field[2]->value[0] = 0x00; zpff->report->field[2]->value[0] = 0x00;
zpff->report->field[3]->value[0] = 0x00; zpff->report->field[3]->value[0] = 0x00;
hid_submit_report(hid, zpff->report, USB_DIR_OUT); usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
printk(KERN_INFO "Force feedback for Zeroplus based devices by " printk(KERN_INFO "Force feedback for Zeroplus based devices by "
"Anssi Hannula <anssi.hannula@gmail.com>\n"); "Anssi Hannula <anssi.hannula@gmail.com>\n");
......
...@@ -240,7 +240,7 @@ static int hiddev_release(struct inode * inode, struct file * file) ...@@ -240,7 +240,7 @@ static int hiddev_release(struct inode * inode, struct file * file)
if (!--list->hiddev->open) { if (!--list->hiddev->open) {
if (list->hiddev->exist) if (list->hiddev->exist)
hid_close(list->hiddev->hid); usbhid_close(list->hiddev->hid);
else else
kfree(list->hiddev); kfree(list->hiddev);
} }
...@@ -271,7 +271,7 @@ static int hiddev_open(struct inode *inode, struct file *file) ...@@ -271,7 +271,7 @@ static int hiddev_open(struct inode *inode, struct file *file)
if (!list->hiddev->open++) if (!list->hiddev->open++)
if (list->hiddev->exist) if (list->hiddev->exist)
hid_open(hiddev_table[i]->hid); usbhid_open(hiddev_table[i]->hid);
return 0; return 0;
} }
...@@ -383,7 +383,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -383,7 +383,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct hiddev_list *list = file->private_data; struct hiddev_list *list = file->private_data;
struct hiddev *hiddev = list->hiddev; struct hiddev *hiddev = list->hiddev;
struct hid_device *hid = hiddev->hid; struct hid_device *hid = hiddev->hid;
struct usb_device *dev = hid->dev; struct usb_device *dev = to_usb_device(hid->dev);
struct hiddev_collection_info cinfo; struct hiddev_collection_info cinfo;
struct hiddev_report_info rinfo; struct hiddev_report_info rinfo;
struct hiddev_field_info finfo; struct hiddev_field_info finfo;
...@@ -392,6 +392,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -392,6 +392,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct hiddev_devinfo dinfo; struct hiddev_devinfo dinfo;
struct hid_report *report; struct hid_report *report;
struct hid_field *field; struct hid_field *field;
struct usbhid_device *usbhid = hid->driver_data;
void __user *user_arg = (void __user *)arg; void __user *user_arg = (void __user *)arg;
int i; int i;
...@@ -421,7 +422,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -421,7 +422,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
dinfo.bustype = BUS_USB; dinfo.bustype = BUS_USB;
dinfo.busnum = dev->bus->busnum; dinfo.busnum = dev->bus->busnum;
dinfo.devnum = dev->devnum; dinfo.devnum = dev->devnum;
dinfo.ifnum = hid->ifnum; dinfo.ifnum = usbhid->ifnum;
dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor); dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
dinfo.product = le16_to_cpu(dev->descriptor.idProduct); dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice); dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
...@@ -480,7 +481,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -480,7 +481,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
} }
case HIDIOCINITREPORT: case HIDIOCINITREPORT:
hid_init_reports(hid); usbhid_init_reports(hid);
return 0; return 0;
...@@ -494,8 +495,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -494,8 +495,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
return -EINVAL; return -EINVAL;
hid_submit_report(hid, report, USB_DIR_IN); usbhid_submit_report(hid, report, USB_DIR_IN);
hid_wait_io(hid); usbhid_wait_io(hid);
return 0; return 0;
...@@ -509,8 +510,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -509,8 +510,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
return -EINVAL; return -EINVAL;
hid_submit_report(hid, report, USB_DIR_OUT); usbhid_submit_report(hid, report, USB_DIR_OUT);
hid_wait_io(hid); usbhid_wait_io(hid);
return 0; return 0;
...@@ -746,6 +747,7 @@ static struct usb_class_driver hiddev_class = { ...@@ -746,6 +747,7 @@ static struct usb_class_driver hiddev_class = {
int hiddev_connect(struct hid_device *hid) int hiddev_connect(struct hid_device *hid)
{ {
struct hiddev *hiddev; struct hiddev *hiddev;
struct usbhid_device *usbhid = hid->driver_data;
int i; int i;
int retval; int retval;
...@@ -761,7 +763,7 @@ int hiddev_connect(struct hid_device *hid) ...@@ -761,7 +763,7 @@ int hiddev_connect(struct hid_device *hid)
if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
return -1; return -1;
retval = usb_register_dev(hid->intf, &hiddev_class); retval = usb_register_dev(usbhid->intf, &hiddev_class);
if (retval) { if (retval) {
err("Not able to get a minor for this device."); err("Not able to get a minor for this device.");
kfree(hiddev); kfree(hiddev);
...@@ -773,10 +775,10 @@ int hiddev_connect(struct hid_device *hid) ...@@ -773,10 +775,10 @@ int hiddev_connect(struct hid_device *hid)
hiddev->hid = hid; hiddev->hid = hid;
hiddev->exist = 1; hiddev->exist = 1;
hid->minor = hid->intf->minor; hid->minor = usbhid->intf->minor;
hid->hiddev = hiddev; hid->hiddev = hiddev;
hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
return 0; return 0;
} }
...@@ -789,14 +791,15 @@ static struct usb_class_driver hiddev_class; ...@@ -789,14 +791,15 @@ static struct usb_class_driver hiddev_class;
void hiddev_disconnect(struct hid_device *hid) void hiddev_disconnect(struct hid_device *hid)
{ {
struct hiddev *hiddev = hid->hiddev; struct hiddev *hiddev = hid->hiddev;
struct usbhid_device *usbhid = hid->driver_data;
hiddev->exist = 0; hiddev->exist = 0;
hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL; hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
usb_deregister_dev(hiddev->hid->intf, &hiddev_class); usb_deregister_dev(usbhid->intf, &hiddev_class);
if (hiddev->open) { if (hiddev->open) {
hid_close(hiddev->hid); usbhid_close(hiddev->hid);
wake_up_interruptible(&hiddev->wait); wake_up_interruptible(&hiddev->wait);
} else { } else {
kfree(hiddev); kfree(hiddev);
......
#ifndef __USBHID_H
#define __USBHID_H
/*
* Copyright (c) 1999 Andreas Gal
* Copyright (c) 2000-2001 Vojtech Pavlik
* Copyright (c) 2006 Jiri Kosina
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/input.h>
/* API provided by hid-core.c for USB HID drivers */
int usbhid_wait_io(struct hid_device* hid);
void usbhid_close(struct hid_device *hid);
int usbhid_open(struct hid_device *hid);
void usbhid_init_reports(struct hid_device *hid);
void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
/*
* USB-specific HID struct, to be pointed to
* from struct hid_device->driver_data
*/
struct usbhid_device {
struct hid_device *hid; /* pointer to corresponding HID dev */
struct usb_interface *intf; /* USB interface */
int ifnum; /* USB interface number */
unsigned int bufsize; /* URB buffer size */
struct urb *urbin; /* Input URB */
char *inbuf; /* Input buffer */
dma_addr_t inbuf_dma; /* Input buffer dma */
spinlock_t inlock; /* Input fifo spinlock */
struct urb *urbctrl; /* Control URB */
struct usb_ctrlrequest *cr; /* Control request struct */
dma_addr_t cr_dma; /* Control request struct dma */
struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */
unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
char *ctrlbuf; /* Control buffer */
dma_addr_t ctrlbuf_dma; /* Control buffer dma */
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; /* Output buffer */
dma_addr_t outbuf_dma; /* Output buffer dma */
spinlock_t outlock; /* Output fifo spinlock */
unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
struct timer_list io_retry; /* Retry timer */
unsigned long stop_retry; /* Time to give up, in jiffies */
unsigned int retry_delay; /* Delay length in ms */
struct work_struct reset_work; /* Task context for resets */
};
#endif
...@@ -410,41 +410,7 @@ struct hid_device { /* device report descriptor */ ...@@ -410,41 +410,7 @@ struct hid_device { /* device report descriptor */
unsigned country; /* HID country */ unsigned country; /* HID country */
struct hid_report_enum report_enum[HID_REPORT_TYPES]; struct hid_report_enum report_enum[HID_REPORT_TYPES];
struct usb_device *dev; /* device */ struct device *dev; /* device */
/* USB specific fields */
struct usb_interface *intf; /* USB interface */
int ifnum; /* USB interface number */
unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
struct timer_list io_retry; /* Retry timer */
unsigned long stop_retry; /* Time to give up, in jiffies */
unsigned int retry_delay; /* Delay length in ms */
struct work_struct reset_work; /* Task context for resets */
unsigned int bufsize; /* URB buffer size */
struct urb *urbin; /* Input URB */
char *inbuf; /* Input buffer */
dma_addr_t inbuf_dma; /* Input buffer dma */
spinlock_t inlock; /* Input fifo spinlock */
struct urb *urbctrl; /* Control URB */
struct usb_ctrlrequest *cr; /* Control request struct */
dma_addr_t cr_dma; /* Control request struct dma */
struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */
unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
char *ctrlbuf; /* Control buffer */
dma_addr_t ctrlbuf_dma; /* Control buffer dma */
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; /* Output buffer */
dma_addr_t outbuf_dma; /* Output buffer dma */
spinlock_t outlock; /* Output fifo spinlock */
unsigned claimed; /* Claimed by hidinput, hiddev? */ unsigned claimed; /* Claimed by hidinput, hiddev? */
unsigned quirks; /* Various quirks the device can pull on us */ unsigned quirks; /* Various quirks the device can pull on us */
......
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