0xC0                    /*  End Collection                          */
 };
 
+/* Parameter indices */
+enum huion_prm {
+       HUION_PRM_X_LM          = 1,
+       HUION_PRM_Y_LM          = 2,
+       HUION_PRM_PRESSURE_LM   = 4,
+       HUION_PRM_RESOLUTION    = 5,
+       HUION_PRM_NUM
+};
+
 /* Driver data */
 struct huion_drvdata {
        __u8 *rdesc;
        int rc;
        struct usb_device *usb_dev = hid_to_usb_dev(hdev);
        struct huion_drvdata *drvdata = hid_get_drvdata(hdev);
-       __le16 buf[6];
+       __le16 *buf = NULL;
+       size_t len;
        s32 params[HUION_PH_ID_NUM];
        s32 resolution;
        __u8 *p;
         * driver traffic.
         * NOTE: This enables fully-functional tablet mode.
         */
+       len = HUION_PRM_NUM * sizeof(*buf);
+       buf = kmalloc(len, GFP_KERNEL);
+       if (buf == NULL) {
+               hid_err(hdev, "failed to allocate parameter buffer\n");
+               rc = -ENOMEM;
+               goto cleanup;
+       }
        rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
                                USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
                                (USB_DT_STRING << 8) + 0x64,
-                               0x0409, buf, sizeof(buf),
+                               0x0409, buf, len,
                                USB_CTRL_GET_TIMEOUT);
        if (rc == -EPIPE) {
                hid_err(hdev, "device parameters not found\n");
-               return -ENODEV;
+               rc = -ENODEV;
+               goto cleanup;
        } else if (rc < 0) {
                hid_err(hdev, "failed to get device parameters: %d\n", rc);
-               return -ENODEV;
-       } else if (rc != sizeof(buf)) {
+               rc = -ENODEV;
+               goto cleanup;
+       } else if (rc != len) {
                hid_err(hdev, "invalid device parameters\n");
-               return -ENODEV;
+               rc = -ENODEV;
+               goto cleanup;
        }
 
        /* Extract device parameters */
-       params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]);
-       params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]);
-       params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]);
-       resolution = le16_to_cpu(buf[5]);
+       params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[HUION_PRM_X_LM]);
+       params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[HUION_PRM_Y_LM]);
+       params[HUION_PH_ID_PRESSURE_LM] =
+               le16_to_cpu(buf[HUION_PRM_PRESSURE_LM]);
+       resolution = le16_to_cpu(buf[HUION_PRM_RESOLUTION]);
        if (resolution == 0) {
                params[HUION_PH_ID_X_PM] = 0;
                params[HUION_PH_ID_Y_PM] = 0;
                                GFP_KERNEL);
        if (drvdata->rdesc == NULL) {
                hid_err(hdev, "failed to allocate fixed rdesc\n");
-               return -ENOMEM;
+               rc = -ENOMEM;
+               goto cleanup;
        }
        drvdata->rsize = sizeof(huion_tablet_rdesc_template);
 
                }
        }
 
-       return 0;
+       rc = 0;
+
+cleanup:
+       kfree(buf);
+       return rc;
 }
 
 static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)