static void usbredir_control_packet(void *priv, uint64_t id,
    struct usb_redir_control_packet_header *control_packet,
    uint8_t *data, int data_len)
{
    USBRedirDevice *dev = priv;
    USBPacket *p;
    int len = control_packet->length;

    DPRINTF("ctrl-in status %d len %d id %"PRIu64"\n", control_packet->status,
            len, id);

    /* Fix up USB-3 ep0 maxpacket size to allow superspeed connected devices
     * to work redirected to a not superspeed capable hcd */
    if (dev->dev.speed == USB_SPEED_SUPER &&
            !((dev->dev.port->speedmask & USB_SPEED_MASK_SUPER)) &&
            control_packet->requesttype == 0x80 &&
            control_packet->request == 6 &&
            control_packet->value == 0x100 && control_packet->index == 0 &&
            data_len >= 18 && data[7] == 9) {
        data[7] = 64;
    }

    p = usbredir_find_packet_by_id(dev, 0, id);
    if (p) {
        usbredir_handle_status(dev, p, control_packet->status);
        if (data_len > 0) {
            usbredir_log_data(dev, "ctrl data in:", data, data_len);
            if (data_len > sizeof(dev->dev.data_buf)) {
                ERROR("ctrl buffer too small (%d > %zu)\n",
                      data_len, sizeof(dev->dev.data_buf));
                p->status = USB_RET_STALL;
                data_len = len = sizeof(dev->dev.data_buf);
            }
            memcpy(dev->dev.data_buf, data, data_len);
        }
        p->actual_length = len;
        /*
         * If this is GET_DESCRIPTOR request for configuration descriptor,
         * remove 'remote wakeup' flag from it to prevent idle power down
         * in Windows guest
         */
        if (dev->suppress_remote_wake &&
            control_packet->requesttype == USB_DIR_IN &&
            control_packet->request == USB_REQ_GET_DESCRIPTOR &&
            control_packet->value == (USB_DT_CONFIG << 8) &&
            control_packet->index == 0 &&
            /* bmAttributes field of config descriptor */
            len > 7 && (dev->dev.data_buf[7] & USB_CFG_ATT_WAKEUP)) {
                DPRINTF("Removed remote wake %04X:%04X\n",
                    dev->device_info.vendor_id,
                    dev->device_info.product_id);
                dev->dev.data_buf[7] &= ~USB_CFG_ATT_WAKEUP;
            }
        usb_generic_async_ctrl_complete(&dev->dev, p);
    }
    free(data);
}
static void usbredir_control_packet(void *priv, uint64_t id,
    struct usb_redir_control_packet_header *control_packet,
    uint8_t *data, int data_len)
{
    USBRedirDevice *dev = priv;
    USBPacket *p;
    int len = control_packet->length;

    DPRINTF("ctrl-in status %d len %d id %"PRIu64"\n", control_packet->status,
            len, id);

     
    if (dev->dev.speed == USB_SPEED_SUPER &&
            !((dev->dev.port->speedmask & USB_SPEED_MASK_SUPER)) &&
            control_packet->requesttype == 0x80 &&
            control_packet->request == 6 &&
            control_packet->value == 0x100 && control_packet->index == 0 &&
            data_len >= 18 && data[7] == 9) {
        data[7] = 64;
    }

    p = usbredir_find_packet_by_id(dev, 0, id);
    if (p) {
        usbredir_handle_status(dev, p, control_packet->status);
        if (data_len > 0) {
            usbredir_log_data(dev, "ctrl data in:", data, data_len);
            if (data_len > sizeof(dev->dev.data_buf)) {
                ERROR("ctrl buffer too small (%d > %zu)\n",
                      data_len, sizeof(dev->dev.data_buf));
                p->status = USB_RET_STALL;
                data_len = len = sizeof(dev->dev.data_buf);
            }
            memcpy(dev->dev.data_buf, data, data_len);
        }
        p->actual_length = len;
         
        if (dev->suppress_remote_wake &&
            control_packet->requesttype == USB_DIR_IN &&
            control_packet->request == USB_REQ_GET_DESCRIPTOR &&
            control_packet->value == (USB_DT_CONFIG << 8) &&
            control_packet->index == 0 &&
             
            len > 7 && (dev->dev.data_buf[7] & USB_CFG_ATT_WAKEUP)) {
                DPRINTF("Removed remote wake %04X:%04X\n",
                    dev->device_info.vendor_id,
                    dev->device_info.product_id);
                dev->dev.data_buf[7] &= ~USB_CFG_ATT_WAKEUP;
            }
        usb_generic_async_ctrl_complete(&dev->dev, p);
    }
    free(data);
}