Re: [PATCH] Alps I2C HID Touchpad-Stick support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 26 May 2016, Masaki Ota wrote:

> Signed-off-by: Masaki Ota <masaki.ota@xxxxxxxxxxx>

Thanks for the patch. However, please supply a changelog; the driver is 
doing non-trivial operations, so at least a bit of explanation (why 
generic HID can't be used, what are interesting high-level properties of 
the protocol, etc.) would be appreciated.

> ---
>  drivers/hid/Makefile   |   1 +
>  drivers/hid/hid-alps.c | 513 +++++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/hid/hid-core.c |   5 +
>  drivers/hid/hid-ids.h  |   2 +
>  include/linux/hid.h    |   1 +

You need to update Kconfig as well, otherwise CONFIG_HID_ALPS wouldn't be 
selectable.

[ .. snip .. ]
> +struct u1_dev *priv;

Having this global is odd. How do you handle multiple devices connected to 
the machine? Is there a reason not to use hid_set_drvdata() / 
hid_get_drvdata() for this?

[ .. snip .. ]
> +static int u1_write_register(struct hid_device *hdev, u32 address, u8 value)
> +{
> +	int ret, i;
> +	u8 input[8];
> +	u8 check_sum;
> +
> +	input[0] = U1_FEATURE_REPORT_ID;
> +	input[1] = U1_CMD_REGISTER_WRITE;
> +	input[2] = address & 0x000000FF;
> +	input[3] = (address & 0x0000FF00) >> 8;
> +	input[4] = (address & 0x00FF0000) >> 16;
> +	input[5] = (address & 0xFF000000) >> 24;
> +	input[6] = value;
> +
> +	/* Calculate the checksum */
> +	check_sum = U1_FEATURE_REPORT_LEN_ALL;
> +	for (i = 0; i < U1_FEATURE_REPORT_LEN - 1; i++)
> +		check_sum += input[i];
> +
> +	input[7] = check_sum;
> +
> +	ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, input,

Looks like on-stack DMA here.

> +static int u1_read_register(struct hid_device *hdev, u32 address, u8 *value)
> +{
> +	int ret, i;
> +	u8 input[8];
> +	u8 readbuf[8];
> +	u8 check_sum;
> +
> +	input[0] = U1_FEATURE_REPORT_ID;
> +	input[1] = U1_CMD_REGISTER_READ;
> +	input[2] = address & 0x000000FF;
> +	input[3] = (address & 0x0000FF00) >> 8;
> +	input[4] = (address & 0x00FF0000) >> 16;
> +	input[5] = (address & 0xFF000000) >> 24;
> +	input[6] = 0x00;
> +
> +	/* Calculate the checksum */
> +	check_sum = U1_FEATURE_REPORT_LEN_ALL;
> +	for (i = 0; i < U1_FEATURE_REPORT_LEN - 1; i++)
> +		check_sum += input[i];
> +
> +	input[7] = check_sum;
> +
> +	ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, input,

The same here.

[ .. snip .. ]

> +static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)
> +{
> +	struct u1_dev *data = hid_get_drvdata(hdev);
> +	struct input_dev *input = hi->input, *input2;
> +	struct u1_dev devInfo;
> +	int ret;
> +	int res_x, res_y, i;
> +
> +	/* Check device product ID*/

Nit: space before the second asterisk please.

> +	switch (hdev->product) {
> +	case HID_PRODUCT_ID_U1:
> +	case HID_PRODUCT_ID_U1_DUAL:
> +		break;
> +	default:
> +		return 0;
> +	}
> +
> +	priv = kzalloc(sizeof(struct u1_dev), GFP_KERNEL);
> +	input2 = input_allocate_device();
> +	if (!priv || !input2)
> +		return 0;

You leak memory in case the kzalloc() succeeds but input_allocate_device() 
fails.

> +
> +	priv->input2 = input2;
> +	data->input = input;
> +
> +	hid_dbg(hdev, "Opening low level driver\n");
> +	ret = hid_hw_open(hdev);
> +	if (ret)
> +		return ret;

Looks like another priv/input2 leak here in case hid_hw_open() fails.

> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index 7e89288..124fc38 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -833,6 +833,11 @@ static int hid_scan_report(struct hid_device *hid)
>  				 */
>  				hid->group = HID_GROUP_RMI;
>  		break;
> +	case USB_VENDOR_ID_ALPS_JP:
> +		if ((hid->group == HID_GROUP_GENERIC) &&
> +			(hid->bus == BUS_I2C))
> +			hid->group = HID_GROUP_ALPS;
> +		break;
>  	}
>  
>  	vfree(parser);
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index b6ff6e7..cac68c7 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -67,6 +67,8 @@
>  #define USB_VENDOR_ID_ALPS		0x0433
>  #define USB_DEVICE_ID_IBM_GAMEPAD	0x1101
>  
> +#define USB_VENDOR_ID_ALPS_JP		0x044E
> +
>  #define USB_VENDOR_ID_ANTON		0x1130
>  #define USB_DEVICE_ID_ANTON_TOUCH_PAD	0x3101
>  
> diff --git a/include/linux/hid.h b/include/linux/hid.h
> index 75b66ec..e35cabf 100644
> --- a/include/linux/hid.h
> +++ b/include/linux/hid.h
> @@ -345,6 +345,7 @@ struct hid_item {
>  #define HID_GROUP_RMI				0x0100
>  #define HID_GROUP_WACOM				0x0101
>  #define HID_GROUP_LOGITECH_DJ_DEVICE		0x0102
> +#define HID_GROUP_ALPS				0x0103

Especially the explanation why you need a separate HID group needs to be 
in the changelog.

Thanks,

-- 
Jiri Kosina
SUSE Labs

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux