@@ -509,9 +509,12 @@ static int uclogic_params_frame_init_v1(struct uclogic_params_frame *frame,
509509void uclogic_params_cleanup (struct uclogic_params * params )
510510{
511511 if (!params -> invalid ) {
512+ size_t i ;
512513 kfree (params -> desc_ptr );
513514 uclogic_params_pen_cleanup (& params -> pen );
514- uclogic_params_frame_cleanup (& params -> frame );
515+ for (i = 0 ; i < ARRAY_SIZE (params -> frame_list ); i ++ ) {
516+ uclogic_params_frame_cleanup (& params -> frame_list [i ]);
517+ }
515518 memset (params , 0 , sizeof (* params ));
516519 }
517520}
@@ -538,60 +541,53 @@ int uclogic_params_get_desc(const struct uclogic_params *params,
538541 __u8 * * pdesc ,
539542 unsigned int * psize )
540543{
541- bool common_present ;
542- bool pen_present ;
543- bool frame_present ;
544- unsigned int size ;
544+ int rc = - ENOMEM ;
545+ bool present = false;
546+ unsigned int size = 0 ;
545547 __u8 * desc = NULL ;
548+ size_t i ;
546549
547550 /* Check arguments */
548551 if (params == NULL || pdesc == NULL || psize == NULL )
549552 return - EINVAL ;
550553
551- size = 0 ;
552-
553- common_present = (params -> desc_ptr != NULL );
554- pen_present = (params -> pen .desc_ptr != NULL );
555- frame_present = (params -> frame .desc_ptr != NULL );
556-
557- if (common_present )
558- size += params -> desc_size ;
559- if (pen_present )
560- size += params -> pen .desc_size ;
561- if (frame_present )
562- size += params -> frame .desc_size ;
563-
564- if (common_present || pen_present || frame_present ) {
565- __u8 * p ;
566-
567- desc = kmalloc (size , GFP_KERNEL );
568- if (desc == NULL )
569- return - ENOMEM ;
570- p = desc ;
571-
572- if (common_present ) {
573- memcpy (p , params -> desc_ptr ,
574- params -> desc_size );
575- p += params -> desc_size ;
576- }
577- if (pen_present ) {
578- memcpy (p , params -> pen .desc_ptr ,
579- params -> pen .desc_size );
580- p += params -> pen .desc_size ;
581- }
582- if (frame_present ) {
583- memcpy (p , params -> frame .desc_ptr ,
584- params -> frame .desc_size );
585- p += params -> frame .desc_size ;
586- }
554+ /* Concatenate descriptors */
555+ #define ADD_DESC (_desc_ptr , _desc_size ) \
556+ do { \
557+ unsigned int new_size; \
558+ __u8 *new_desc; \
559+ if ((_desc_ptr) == NULL) { \
560+ break; \
561+ } \
562+ new_size = size + (_desc_size); \
563+ new_desc = krealloc(desc, new_size, GFP_KERNEL); \
564+ if (new_desc == NULL) { \
565+ goto cleanup; \
566+ } \
567+ memcpy(new_desc + size, (_desc_ptr), (_desc_size)); \
568+ desc = new_desc; \
569+ size = new_size; \
570+ present = true; \
571+ } while (0)
572+
573+ ADD_DESC (params -> desc_ptr , params -> desc_size );
574+ ADD_DESC (params -> pen .desc_ptr , params -> pen .desc_size );
575+ for (i = 0 ; i < ARRAY_SIZE (params -> frame_list ); i ++ ) {
576+ ADD_DESC (params -> frame_list [i ].desc_ptr ,
577+ params -> frame_list [i ].desc_size );
578+ }
587579
588- WARN_ON ( p != desc + size );
580+ #undef ADD_DESC
589581
582+ if (present ) {
583+ * pdesc = desc ;
590584 * psize = size ;
585+ desc = NULL ;
591586 }
592-
593- * pdesc = desc ;
594- return 0 ;
587+ rc = 0 ;
588+ cleanup :
589+ kfree (desc );
590+ return rc ;
595591}
596592
597593/**
@@ -743,7 +739,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
743739 hid_dbg (hdev , "pen v2 parameters found\n" );
744740 /* Create v2 frame parameters */
745741 rc = uclogic_params_frame_init_with_desc (
746- & p .frame ,
742+ & p .frame_list [ 0 ] ,
747743 uclogic_rdesc_v2_frame_arr ,
748744 uclogic_rdesc_v2_frame_size ,
749745 UCLOGIC_RDESC_V2_FRAME_ID );
@@ -771,7 +767,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
771767 } else if (found ) {
772768 hid_dbg (hdev , "pen v1 parameters found\n" );
773769 /* Try to probe v1 frame */
774- rc = uclogic_params_frame_init_v1 (& p .frame ,
770+ rc = uclogic_params_frame_init_v1 (& p .frame_list [ 0 ] ,
775771 & found , hdev );
776772 if (rc != 0 ) {
777773 hid_err (hdev , "v1 frame probing failed: %d\n" , rc );
@@ -1022,7 +1018,7 @@ int uclogic_params_init(struct uclogic_params *params,
10221018 }
10231019 /* Initialize frame parameters */
10241020 rc = uclogic_params_frame_init_with_desc (
1025- & p .frame ,
1021+ & p .frame_list [ 0 ] ,
10261022 uclogic_rdesc_xppen_deco01_frame_arr ,
10271023 uclogic_rdesc_xppen_deco01_frame_size ,
10281024 0 );
@@ -1046,7 +1042,7 @@ int uclogic_params_init(struct uclogic_params *params,
10461042 goto cleanup ;
10471043 } else if (found ) {
10481044 rc = uclogic_params_frame_init_with_desc (
1049- & p .frame ,
1045+ & p .frame_list [ 0 ] ,
10501046 uclogic_rdesc_ugee_g5_frame_arr ,
10511047 uclogic_rdesc_ugee_g5_frame_size ,
10521048 UCLOGIC_RDESC_UGEE_G5_FRAME_ID );
@@ -1056,9 +1052,9 @@ int uclogic_params_init(struct uclogic_params *params,
10561052 rc );
10571053 goto cleanup ;
10581054 }
1059- p .frame .re_lsb =
1055+ p .frame_list [ 0 ] .re_lsb =
10601056 UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB ;
1061- p .frame .dev_id_byte =
1057+ p .frame_list [ 0 ] .dev_id_byte =
10621058 UCLOGIC_RDESC_UGEE_G5_FRAME_DEV_ID_BYTE ;
10631059 } else {
10641060 hid_warn (hdev , "pen parameters not found" );
@@ -1080,7 +1076,7 @@ int uclogic_params_init(struct uclogic_params *params,
10801076 goto cleanup ;
10811077 } else if (found ) {
10821078 rc = uclogic_params_frame_init_with_desc (
1083- & p .frame ,
1079+ & p .frame_list [ 0 ] ,
10841080 uclogic_rdesc_ugee_ex07_frame_arr ,
10851081 uclogic_rdesc_ugee_ex07_frame_size ,
10861082 0 );
0 commit comments