Skip to content

Commit a99ecb8

Browse files
committed
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.
1 parent ed990d7 commit a99ecb8

1 file changed

Lines changed: 58 additions & 34 deletions

File tree

hid-uclogic-params.c

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

410428
/*
@@ -428,8 +446,6 @@ static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
428446
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 /
429447
resolution;
430448
}
431-
kfree(buf);
432-
buf = NULL;
433449

434450
/*
435451
* Generate pen report descriptor
@@ -455,6 +471,13 @@ static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
455471
pen->fragmented_hires = true;
456472
pen->tilt_y_flipped = true;
457473
found = true;
474+
if (pparams_ptr != NULL) {
475+
*pparams_ptr = buf;
476+
buf = NULL;
477+
}
478+
if (pparams_len != NULL) {
479+
*pparams_len = params_len;
480+
}
458481
finish:
459482
*pfound = found;
460483
rc = 0;
@@ -820,7 +843,8 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
820843
"transition firmware detected, not probing pen v2 parameters\n");
821844
} else {
822845
/* Try to probe v2 pen parameters */
823-
rc = uclogic_params_pen_init_v2(&p.pen, &found, hdev);
846+
rc = uclogic_params_pen_init_v2(&p.pen, &found,
847+
NULL, NULL, hdev);
824848
if (rc != 0) {
825849
hid_err(hdev,
826850
"failed probing pen v2 parameters: %d\n", rc);

0 commit comments

Comments
 (0)