Skip to content

Commit 945d5dd

Browse files
spbnickJiri Kosina
authored andcommitted
HID: uclogic: Return raw parameters from v2 pen init
Return the raw parameters buffer from uclogic_params_pen_init_v2(), if requested, as a way to identify the tablet. Signed-off-by: Nikolai Kondrashov <[email protected]> Signed-off-by: José Expósito <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent a228809 commit 945d5dd

File tree

1 file changed

+58
-34
lines changed

1 file changed

+58
-34
lines changed

drivers/hid/hid-uclogic-params.c

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -338,28 +338,45 @@ static s32 uclogic_params_get_le24(const void *p)
338338
* uclogic_params_pen_init_v2() - initialize tablet interface pen
339339
* input and retrieve its parameters from the device, using v2 protocol.
340340
*
341-
* @pen: Pointer to the pen parameters to initialize (to be
342-
* cleaned up with uclogic_params_pen_cleanup()). Not modified in
343-
* case of error, or if parameters are not found. Cannot be NULL.
344-
* @pfound: Location for a flag which is set to true if the parameters
345-
* were found, and to false if not (e.g. device was
346-
* incompatible). Not modified in case of error. Cannot be NULL.
347-
* @hdev: The HID device of the tablet interface to initialize and get
348-
* parameters from. Cannot be NULL.
341+
* @pen: Pointer to the pen parameters to initialize (to be
342+
* cleaned up with uclogic_params_pen_cleanup()). Not
343+
* modified in case of error, or if parameters are not
344+
* found. Cannot be NULL.
345+
* @pfound: Location for a flag which is set to true if the
346+
* parameters were found, and to false if not (e.g.
347+
* device was incompatible). Not modified in case of
348+
* error. Cannot be NULL.
349+
* @pparams_ptr: Location for a kmalloc'ed pointer to the retrieved raw
350+
* parameters, which could be used to identify the tablet
351+
* to some extent. Should be freed with kfree after use.
352+
* NULL, if not needed. Not modified in case of error.
353+
* Only set if *pfound is set to true.
354+
* @pparams_len: Location for the length of the retrieved raw
355+
* parameters. NULL, if not needed. Not modified in case
356+
* of error. Only set if *pfound is set to true.
357+
* @hdev: The HID device of the tablet interface to initialize
358+
* and get parameters from. Cannot be NULL.
349359
*
350360
* Returns:
351361
* Zero, if successful. A negative errno code on error.
352362
*/
353363
static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
354364
bool *pfound,
365+
__u8 **pparams_ptr,
366+
size_t *pparams_len,
355367
struct hid_device *hdev)
356368
{
357369
int rc;
358370
bool found = false;
359-
/* Buffer for (part of) the string descriptor */
371+
/* Buffer for (part of) the parameter string descriptor */
360372
__u8 *buf = NULL;
361-
/* Descriptor length required */
362-
const int len = 18;
373+
/* Parameter string descriptor required length */
374+
const int params_len_min = 18;
375+
/* Parameter string descriptor accepted length */
376+
const int params_len_max = 32;
377+
/* Parameter string descriptor received length */
378+
int params_len;
379+
size_t i;
363380
s32 resolution;
364381
/* Pen report descriptor template parameters */
365382
s32 desc_params[UCLOGIC_RDESC_PEN_PH_ID_NUM];
@@ -377,35 +394,36 @@ static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
377394
* the Windows driver traffic.
378395
* NOTE: This enables fully-functional tablet mode.
379396
*/
380-
rc = uclogic_params_get_str_desc(&buf, hdev, 200, len);
397+
rc = uclogic_params_get_str_desc(&buf, hdev, 200, params_len_max);
381398
if (rc == -EPIPE) {
382399
hid_dbg(hdev,
383400
"string descriptor with pen parameters not found, assuming not compatible\n");
384401
goto finish;
385402
} else if (rc < 0) {
386403
hid_err(hdev, "failed retrieving pen parameters: %d\n", rc);
387404
goto cleanup;
388-
} else if (rc != len) {
405+
} else if (rc < params_len_min) {
389406
hid_dbg(hdev,
390-
"string descriptor with pen parameters has invalid length (got %d, expected %d), assuming not compatible\n",
391-
rc, len);
407+
"string descriptor with pen parameters is too short (got %d, expected at least %d), assuming not compatible\n",
408+
rc, params_len_min);
409+
goto finish;
410+
}
411+
412+
params_len = rc;
413+
414+
/*
415+
* Check it's not just a catch-all UTF-16LE-encoded ASCII
416+
* string (such as the model name) some tablets put into all
417+
* unknown string descriptors.
418+
*/
419+
for (i = 2;
420+
i < params_len &&
421+
(buf[i] >= 0x20 && buf[i] < 0x7f && buf[i + 1] == 0);
422+
i += 2);
423+
if (i >= params_len) {
424+
hid_dbg(hdev,
425+
"string descriptor with pen parameters seems to contain only text, assuming not compatible\n");
392426
goto finish;
393-
} else {
394-
size_t i;
395-
/*
396-
* Check it's not just a catch-all UTF-16LE-encoded ASCII
397-
* string (such as the model name) some tablets put into all
398-
* unknown string descriptors.
399-
*/
400-
for (i = 2;
401-
i < len &&
402-
(buf[i] >= 0x20 && buf[i] < 0x7f && buf[i + 1] == 0);
403-
i += 2);
404-
if (i >= len) {
405-
hid_dbg(hdev,
406-
"string descriptor with pen parameters seems to contain only text, assuming not compatible\n");
407-
goto finish;
408-
}
409427
}
410428

411429
/*
@@ -429,8 +447,6 @@ static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
429447
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 /
430448
resolution;
431449
}
432-
kfree(buf);
433-
buf = NULL;
434450

435451
/*
436452
* Generate pen report descriptor
@@ -456,6 +472,13 @@ static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
456472
pen->fragmented_hires = true;
457473
pen->tilt_y_flipped = true;
458474
found = true;
475+
if (pparams_ptr != NULL) {
476+
*pparams_ptr = buf;
477+
buf = NULL;
478+
}
479+
if (pparams_len != NULL)
480+
*pparams_len = params_len;
481+
459482
finish:
460483
*pfound = found;
461484
rc = 0;
@@ -828,7 +851,8 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
828851
"transition firmware detected, not probing pen v2 parameters\n");
829852
} else {
830853
/* Try to probe v2 pen parameters */
831-
rc = uclogic_params_pen_init_v2(&p.pen, &found, hdev);
854+
rc = uclogic_params_pen_init_v2(&p.pen, &found,
855+
NULL, NULL, hdev);
832856
if (rc != 0) {
833857
hid_err(hdev,
834858
"failed probing pen v2 parameters: %d\n", rc);

0 commit comments

Comments
 (0)