@@ -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 */
353363static 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+
459482finish :
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