@@ -512,9 +512,12 @@ static int uclogic_params_frame_init_v1(struct uclogic_params_frame *frame,
512512void uclogic_params_cleanup (struct uclogic_params * params )
513513{
514514 if (!params -> invalid ) {
515+ size_t i ;
515516 kfree (params -> desc_ptr );
516517 uclogic_params_pen_cleanup (& params -> pen );
517- uclogic_params_frame_cleanup (& params -> frame );
518+ for (i = 0 ; i < ARRAY_SIZE (params -> frame_list ); i ++ )
519+ uclogic_params_frame_cleanup (& params -> frame_list [i ]);
520+
518521 memset (params , 0 , sizeof (* params ));
519522 }
520523}
@@ -542,60 +545,53 @@ int uclogic_params_get_desc(const struct uclogic_params *params,
542545 __u8 * * pdesc ,
543546 unsigned int * psize )
544547{
545- bool common_present ;
546- bool pen_present ;
547- bool frame_present ;
548- unsigned int size ;
548+ int rc = - ENOMEM ;
549+ bool present = false;
550+ unsigned int size = 0 ;
549551 __u8 * desc = NULL ;
552+ size_t i ;
550553
551554 /* Check arguments */
552555 if (params == NULL || pdesc == NULL || psize == NULL )
553556 return - EINVAL ;
554557
555- size = 0 ;
556-
557- common_present = (params -> desc_ptr != NULL );
558- pen_present = (params -> pen .desc_ptr != NULL );
559- frame_present = (params -> frame .desc_ptr != NULL );
560-
561- if (common_present )
562- size += params -> desc_size ;
563- if (pen_present )
564- size += params -> pen .desc_size ;
565- if (frame_present )
566- size += params -> frame .desc_size ;
567-
568- if (common_present || pen_present || frame_present ) {
569- __u8 * p ;
570-
571- desc = kmalloc (size , GFP_KERNEL );
572- if (desc == NULL )
573- return - ENOMEM ;
574- p = desc ;
575-
576- if (common_present ) {
577- memcpy (p , params -> desc_ptr ,
578- params -> desc_size );
579- p += params -> desc_size ;
580- }
581- if (pen_present ) {
582- memcpy (p , params -> pen .desc_ptr ,
583- params -> pen .desc_size );
584- p += params -> pen .desc_size ;
585- }
586- if (frame_present ) {
587- memcpy (p , params -> frame .desc_ptr ,
588- params -> frame .desc_size );
589- p += params -> frame .desc_size ;
590- }
558+ /* Concatenate descriptors */
559+ #define ADD_DESC (_desc_ptr , _desc_size ) \
560+ do { \
561+ unsigned int new_size; \
562+ __u8 *new_desc; \
563+ if ((_desc_ptr) == NULL) { \
564+ break; \
565+ } \
566+ new_size = size + (_desc_size); \
567+ new_desc = krealloc(desc, new_size, GFP_KERNEL); \
568+ if (new_desc == NULL) { \
569+ goto cleanup; \
570+ } \
571+ memcpy(new_desc + size, (_desc_ptr), (_desc_size)); \
572+ desc = new_desc; \
573+ size = new_size; \
574+ present = true; \
575+ } while (0)
576+
577+ ADD_DESC (params -> desc_ptr , params -> desc_size );
578+ ADD_DESC (params -> pen .desc_ptr , params -> pen .desc_size );
579+ for (i = 0 ; i < ARRAY_SIZE (params -> frame_list ); i ++ ) {
580+ ADD_DESC (params -> frame_list [i ].desc_ptr ,
581+ params -> frame_list [i ].desc_size );
582+ }
591583
592- WARN_ON ( p != desc + size );
584+ #undef ADD_DESC
593585
586+ if (present ) {
587+ * pdesc = desc ;
594588 * psize = size ;
589+ desc = NULL ;
595590 }
596-
597- * pdesc = desc ;
598- return 0 ;
591+ rc = 0 ;
592+ cleanup :
593+ kfree (desc );
594+ return rc ;
599595}
600596
601597/**
@@ -751,7 +747,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
751747 hid_dbg (hdev , "pen v2 parameters found\n" );
752748 /* Create v2 frame parameters */
753749 rc = uclogic_params_frame_init_with_desc (
754- & p .frame ,
750+ & p .frame_list [ 0 ] ,
755751 uclogic_rdesc_v2_frame_arr ,
756752 uclogic_rdesc_v2_frame_size ,
757753 UCLOGIC_RDESC_V2_FRAME_ID );
@@ -779,7 +775,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
779775 } else if (found ) {
780776 hid_dbg (hdev , "pen v1 parameters found\n" );
781777 /* Try to probe v1 frame */
782- rc = uclogic_params_frame_init_v1 (& p .frame ,
778+ rc = uclogic_params_frame_init_v1 (& p .frame_list [ 0 ] ,
783779 & found , hdev );
784780 if (rc != 0 ) {
785781 hid_err (hdev , "v1 frame probing failed: %d\n" , rc );
@@ -1033,7 +1029,7 @@ int uclogic_params_init(struct uclogic_params *params,
10331029 }
10341030 /* Initialize frame parameters */
10351031 rc = uclogic_params_frame_init_with_desc (
1036- & p .frame ,
1032+ & p .frame_list [ 0 ] ,
10371033 uclogic_rdesc_xppen_deco01_frame_arr ,
10381034 uclogic_rdesc_xppen_deco01_frame_size ,
10391035 0 );
@@ -1059,7 +1055,7 @@ int uclogic_params_init(struct uclogic_params *params,
10591055 goto cleanup ;
10601056 } else if (found ) {
10611057 rc = uclogic_params_frame_init_with_desc (
1062- & p .frame ,
1058+ & p .frame_list [ 0 ] ,
10631059 uclogic_rdesc_ugee_g5_frame_arr ,
10641060 uclogic_rdesc_ugee_g5_frame_size ,
10651061 UCLOGIC_RDESC_UGEE_G5_FRAME_ID );
@@ -1069,9 +1065,9 @@ int uclogic_params_init(struct uclogic_params *params,
10691065 rc );
10701066 goto cleanup ;
10711067 }
1072- p .frame .re_lsb =
1068+ p .frame_list [ 0 ] .re_lsb =
10731069 UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB ;
1074- p .frame .dev_id_byte =
1070+ p .frame_list [ 0 ] .dev_id_byte =
10751071 UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE ;
10761072 } else {
10771073 hid_warn (hdev , "pen parameters not found" );
@@ -1093,7 +1089,7 @@ int uclogic_params_init(struct uclogic_params *params,
10931089 goto cleanup ;
10941090 } else if (found ) {
10951091 rc = uclogic_params_frame_init_with_desc (
1096- & p .frame ,
1092+ & p .frame_list [ 0 ] ,
10971093 uclogic_rdesc_ugee_ex07_frame_arr ,
10981094 uclogic_rdesc_ugee_ex07_frame_size ,
10991095 0 );
0 commit comments