@@ -84,6 +84,15 @@ static const __u8 huion_tablet_rdesc_template[] = {
8484 0xC0 /* End Collection */
8585};
8686
87+ /* Parameter indices */
88+ enum huion_prm {
89+ HUION_PRM_X_LM = 1 ,
90+ HUION_PRM_Y_LM = 2 ,
91+ HUION_PRM_PRESSURE_LM = 4 ,
92+ HUION_PRM_RESOLUTION = 5 ,
93+ HUION_PRM_NUM
94+ };
95+
8796/* Driver data */
8897struct huion_drvdata {
8998 __u8 * rdesc ;
@@ -115,7 +124,8 @@ static int huion_tablet_enable(struct hid_device *hdev)
115124 int rc ;
116125 struct usb_device * usb_dev = hid_to_usb_dev (hdev );
117126 struct huion_drvdata * drvdata = hid_get_drvdata (hdev );
118- __le16 buf [6 ];
127+ __le16 * buf = NULL ;
128+ size_t len ;
119129 s32 params [HUION_PH_ID_NUM ];
120130 s32 resolution ;
121131 __u8 * p ;
@@ -127,27 +137,38 @@ static int huion_tablet_enable(struct hid_device *hdev)
127137 * driver traffic.
128138 * NOTE: This enables fully-functional tablet mode.
129139 */
140+ len = HUION_PRM_NUM * sizeof (* buf );
141+ buf = kmalloc (len , GFP_KERNEL );
142+ if (buf == NULL ) {
143+ hid_err (hdev , "failed to allocate parameter buffer\n" );
144+ rc = - ENOMEM ;
145+ goto cleanup ;
146+ }
130147 rc = usb_control_msg (usb_dev , usb_rcvctrlpipe (usb_dev , 0 ),
131148 USB_REQ_GET_DESCRIPTOR , USB_DIR_IN ,
132149 (USB_DT_STRING << 8 ) + 0x64 ,
133- 0x0409 , buf , sizeof ( buf ) ,
150+ 0x0409 , buf , len ,
134151 USB_CTRL_GET_TIMEOUT );
135152 if (rc == - EPIPE ) {
136153 hid_err (hdev , "device parameters not found\n" );
137- return - ENODEV ;
154+ rc = - ENODEV ;
155+ goto cleanup ;
138156 } else if (rc < 0 ) {
139157 hid_err (hdev , "failed to get device parameters: %d\n" , rc );
140- return - ENODEV ;
141- } else if (rc != sizeof (buf )) {
158+ rc = - ENODEV ;
159+ goto cleanup ;
160+ } else if (rc != len ) {
142161 hid_err (hdev , "invalid device parameters\n" );
143- return - ENODEV ;
162+ rc = - ENODEV ;
163+ goto cleanup ;
144164 }
145165
146166 /* Extract device parameters */
147- params [HUION_PH_ID_X_LM ] = le16_to_cpu (buf [1 ]);
148- params [HUION_PH_ID_Y_LM ] = le16_to_cpu (buf [2 ]);
149- params [HUION_PH_ID_PRESSURE_LM ] = le16_to_cpu (buf [4 ]);
150- resolution = le16_to_cpu (buf [5 ]);
167+ params [HUION_PH_ID_X_LM ] = le16_to_cpu (buf [HUION_PRM_X_LM ]);
168+ params [HUION_PH_ID_Y_LM ] = le16_to_cpu (buf [HUION_PRM_Y_LM ]);
169+ params [HUION_PH_ID_PRESSURE_LM ] =
170+ le16_to_cpu (buf [HUION_PRM_PRESSURE_LM ]);
171+ resolution = le16_to_cpu (buf [HUION_PRM_RESOLUTION ]);
151172 if (resolution == 0 ) {
152173 params [HUION_PH_ID_X_PM ] = 0 ;
153174 params [HUION_PH_ID_Y_PM ] = 0 ;
@@ -164,7 +185,8 @@ static int huion_tablet_enable(struct hid_device *hdev)
164185 GFP_KERNEL );
165186 if (drvdata -> rdesc == NULL ) {
166187 hid_err (hdev , "failed to allocate fixed rdesc\n" );
167- return - ENOMEM ;
188+ rc = - ENOMEM ;
189+ goto cleanup ;
168190 }
169191 drvdata -> rsize = sizeof (huion_tablet_rdesc_template );
170192
@@ -183,7 +205,11 @@ static int huion_tablet_enable(struct hid_device *hdev)
183205 }
184206 }
185207
186- return 0 ;
208+ rc = 0 ;
209+
210+ cleanup :
211+ kfree (buf );
212+ return rc ;
187213}
188214
189215static int huion_probe (struct hid_device * hdev , const struct hid_device_id * id )
0 commit comments