@@ -338,28 +338,45 @@ static s32 uclogic_params_get_le24(const void *p)
338
338
* uclogic_params_pen_init_v2() - initialize tablet interface pen
339
339
* input and retrieve its parameters from the device, using v2 protocol.
340
340
*
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.
349
359
*
350
360
* Returns:
351
361
* Zero, if successful. A negative errno code on error.
352
362
*/
353
363
static int uclogic_params_pen_init_v2 (struct uclogic_params_pen * pen ,
354
364
bool * pfound ,
365
+ __u8 * * pparams_ptr ,
366
+ size_t * pparams_len ,
355
367
struct hid_device * hdev )
356
368
{
357
369
int rc ;
358
370
bool found = false;
359
- /* Buffer for (part of) the string descriptor */
371
+ /* Buffer for (part of) the parameter string descriptor */
360
372
__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 ;
363
380
s32 resolution ;
364
381
/* Pen report descriptor template parameters */
365
382
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,
377
394
* the Windows driver traffic.
378
395
* NOTE: This enables fully-functional tablet mode.
379
396
*/
380
- rc = uclogic_params_get_str_desc (& buf , hdev , 200 , len );
397
+ rc = uclogic_params_get_str_desc (& buf , hdev , 200 , params_len_max );
381
398
if (rc == - EPIPE ) {
382
399
hid_dbg (hdev ,
383
400
"string descriptor with pen parameters not found, assuming not compatible\n" );
384
401
goto finish ;
385
402
} else if (rc < 0 ) {
386
403
hid_err (hdev , "failed retrieving pen parameters: %d\n" , rc );
387
404
goto cleanup ;
388
- } else if (rc != len ) {
405
+ } else if (rc < params_len_min ) {
389
406
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" );
392
426
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
- }
409
427
}
410
428
411
429
/*
@@ -429,8 +447,6 @@ static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
429
447
desc_params [UCLOGIC_RDESC_PEN_PH_ID_Y_LM ] * 1000 /
430
448
resolution ;
431
449
}
432
- kfree (buf );
433
- buf = NULL ;
434
450
435
451
/*
436
452
* Generate pen report descriptor
@@ -456,6 +472,13 @@ static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
456
472
pen -> fragmented_hires = true;
457
473
pen -> tilt_y_flipped = true;
458
474
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
+
459
482
finish :
460
483
* pfound = found ;
461
484
rc = 0 ;
@@ -828,7 +851,8 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
828
851
"transition firmware detected, not probing pen v2 parameters\n" );
829
852
} else {
830
853
/* 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 );
832
856
if (rc != 0 ) {
833
857
hid_err (hdev ,
834
858
"failed probing pen v2 parameters: %d\n" , rc );
0 commit comments