Re: [linux-usb-devel] [RFC] HID bus design overview.

Li Yu
2007-04-02T01:48:24Z

Jiri Kosina wrote:
> On Fri, 30 Mar 2007, Dmitry Torokhov wrote:
>
>
>> There should be one device and your driver should simply do:
>> static void my_driver_hid_event(struct hid_device *hid, struct hid_field *field,
>> struct hid_usage *usage, __s32 value)
>> {
>> if (special_processing_needed(usage)) {
>> do_special_processing(...);
>> input_event(field->hidinput->input, XXX, YYY, ZZZ);
>> ...
>>
>> } else
>> hidinput_hid_event(hid, field, usage, value);
>> }
>>
>
> Hi,
>
> in fact I am not entirely sure that the specialized drivers hooked to the
> HID bus should be passed individual fields/usages by the generic HID
> driver. That would imply that generic HID layer would have to parse the
> received report using information retrieved from the report descriptor of
> the device. But this is in some way in contrary to one of the features
> this effort should be heading to, isn't it? We want to provide means how
> to bypass possible errors in HID descriptor of the device (or do any other
> possible quirky handling) - we want to be able to allow for completely
> different interpretation of fields than the generic HID parser would do,
> right?
>
> So I guess the above should rather be
>
> static void my_driver_hid_report(struct hid_device *hid, u8 *data,
> int size)
> {
> if (special_processing_needed(data)) {
> do_special_processing(...);
> input_event(field->hidinput->input, XXX, YYY, ZZZ);
> ...
> } else
> hid_input_report(hid, data, size);
> }
>
>
> Such driver will register itself onto a HID bus. Both USB and BT
> transports could provide VID and PID which could then be easily matched
> against by the bus code to easily check whether processing by specialized
> driver is needed or handling by (existing) generic HID layer is enough.
>
> As an added value, hooking the hidraw code to this architecture would then
> be rather a trivial task.
>
> Thanks,
>
>
Let me explain the internal of my current HID bus implementation. I
think that selecting one user scene as example is good idea.

Well, the user A plug a USB joystick into computer. The work processing
of HID subsystem for this joystick is same with our mind: The USB/base
driver works for it. However, the world is not faultless. This joystick
is buggy, its some keys need specific handling, our good friend udev
discover that there is also have another driver can handle it, so it
insert that kernel module, then our sweet leading role specific/shadow
HID driver appear on scene. Registering shadow driver let HID core clone
a hid_device first, and start new usage configuration processing for new
cloned hid_device (if we like, even I think we can reread reports from
physical device), the shadow driver can join with HID core to
custom/hook in this recofiguration processing. If this shadow driver is
input-able, the HID core will unregister working input device come from
USB/base hid_device, and register new input device for this shadow
hid_device. So we have not two input_dev for one HID device at same time.

When user A remove this shadow driver, the USB/base driver should resume
work for this joystick, IOW, it should register back its input device again.

There have another type driver: the sticky driver, they will attach each
working device without clone or create new hid_device or input_dev. the
example is hiddev and hidraw.

Yes, this model imply there need more uevents: add, remove. Is this
model suitable? I think the essence of our discussion is how to handle
unknown abnormal device.

I had already ported this to 2.6.21-rc5-mm2, and spent almost two days
to find out one concurrency problem. I lucky known where have bug, but
not fixed it.

Good luck.

- Li Yu