亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? usb-linux.c

?? QEMU 0.91 source code, supports ARM processor including S3C24xx series
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* * Linux host USB redirector * * Copyright (c) 2005 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */#include "qemu-common.h"#include "hw/usb.h"#include "console.h"#if defined(__linux__)#include <dirent.h>#include <sys/ioctl.h>#include <linux/usbdevice_fs.h>#include <linux/version.h>#include <signal.h>/* We redefine it to avoid version problems */struct usb_ctrltransfer {    uint8_t  bRequestType;    uint8_t  bRequest;    uint16_t wValue;    uint16_t wIndex;    uint16_t wLength;    uint32_t timeout;    void *data;};typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,                        int vendor_id, int product_id,                        const char *product_name, int speed);static int usb_host_find_device(int *pbus_num, int *paddr,                                char *product_name, int product_name_size,                                const char *devname);//#define DEBUG//#define DEBUG_ISOCH//#define USE_ASYNCIO#define USBDEVFS_PATH "/proc/bus/usb"#define PRODUCT_NAME_SZ 32#define SIG_ISOCOMPLETE (SIGRTMIN+7)#define MAX_ENDPOINTS 16struct sigaction sigact;/* endpoint association data */struct endp_data {    uint8_t type;};/* FIXME: move USBPacket to PendingURB */typedef struct USBHostDevice {    USBDevice dev;    int fd;    int pipe_fds[2];    USBPacket *packet;    struct endp_data endp_table[MAX_ENDPOINTS];    int configuration;    uint8_t descr[1024];    int descr_len;    int urbs_ready;} USBHostDevice;typedef struct PendingURB {    struct usbdevfs_urb *urb;    int status;    struct PendingURB *next;} PendingURB;static PendingURB *pending_urbs = NULL;static int add_pending_urb(struct usbdevfs_urb *urb){    PendingURB *purb = qemu_mallocz(sizeof(PendingURB));    if (purb) {        purb->urb = urb;        purb->status = 0;        purb->next = pending_urbs;        pending_urbs = purb;        return 1;    }    return 0;}static int del_pending_urb(struct usbdevfs_urb *urb){    PendingURB *purb = pending_urbs;    PendingURB *prev = NULL;    while (purb && purb->urb != urb) {        prev = purb;        purb = purb->next;    }    if (purb && purb->urb == urb) {        if (prev) {            prev->next = purb->next;        } else {            pending_urbs = purb->next;        }        qemu_free(purb);        return 1;    }    return 0;}#ifdef USE_ASYNCIOstatic PendingURB *get_pending_urb(struct usbdevfs_urb *urb){    PendingURB *purb = pending_urbs;    while (purb && purb->urb != urb) {        purb = purb->next;    }    if (purb && purb->urb == urb) {        return purb;    }    return NULL;}#endifstatic int usb_host_update_interfaces(USBHostDevice *dev, int configuration){    int dev_descr_len, config_descr_len;    int interface, nb_interfaces, nb_configurations;    int ret, i;    if (configuration == 0) /* address state - ignore */        return 1;    i = 0;    dev_descr_len = dev->descr[0];    if (dev_descr_len > dev->descr_len)        goto fail;    nb_configurations = dev->descr[17];    i += dev_descr_len;    while (i < dev->descr_len) {#ifdef DEBUG        printf("i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len,               dev->descr[i], dev->descr[i+1]);#endif        if (dev->descr[i+1] != USB_DT_CONFIG) {            i += dev->descr[i];            continue;        }        config_descr_len = dev->descr[i];        if (configuration == dev->descr[i + 5])            break;        i += config_descr_len;    }    if (i >= dev->descr_len) {        printf("usb_host: error - device has no matching configuration\n");        goto fail;    }    nb_interfaces = dev->descr[i + 4];#ifdef USBDEVFS_DISCONNECT    /* earlier Linux 2.4 do not support that */    {        struct usbdevfs_ioctl ctrl;        for (interface = 0; interface < nb_interfaces; interface++) {            ctrl.ioctl_code = USBDEVFS_DISCONNECT;            ctrl.ifno = interface;            ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);            if (ret < 0 && errno != ENODATA) {                perror("USBDEVFS_DISCONNECT");                goto fail;            }        }    }#endif    /* XXX: only grab if all interfaces are free */    for (interface = 0; interface < nb_interfaces; interface++) {        ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);        if (ret < 0) {            if (errno == EBUSY) {                fprintf(stderr,                        "usb_host: warning - device already grabbed\n");            } else {                perror("USBDEVFS_CLAIMINTERFACE");            }        fail:            return 0;        }    }#ifdef DEBUG    printf("usb_host: %d interfaces claimed for configuration %d\n",           nb_interfaces, configuration);#endif    return 1;}static void usb_host_handle_reset(USBDevice *dev){#if 0    USBHostDevice *s = (USBHostDevice *)dev;    /* USBDEVFS_RESET, but not the first time as it has already be       done by the host OS */    ioctl(s->fd, USBDEVFS_RESET);#endif}static void usb_host_handle_destroy(USBDevice *dev){    USBHostDevice *s = (USBHostDevice *)dev;    if (s->fd >= 0)        close(s->fd);    qemu_free(s);}static int usb_linux_update_endp_table(USBHostDevice *s);static int usb_host_handle_control(USBDevice *dev,                                   int request,                                   int value,                                   int index,                                   int length,                                   uint8_t *data){    USBHostDevice *s = (USBHostDevice *)dev;    struct usb_ctrltransfer ct;    struct usbdevfs_setinterface si;    int intf_update_required = 0;    int ret;    if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {        /* specific SET_ADDRESS support */        dev->addr = value;        return 0;    } else if (request == ((USB_RECIP_INTERFACE << 8) |                           USB_REQ_SET_INTERFACE)) {        /* set alternate setting for the interface */        si.interface = index;        si.altsetting = value;        ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);        usb_linux_update_endp_table(s);    } else if (request == (DeviceOutRequest | USB_REQ_SET_CONFIGURATION)) {#ifdef DEBUG        printf("usb_host_handle_control: SET_CONFIGURATION request - "               "config %d\n", value & 0xff);#endif        if (s->configuration != (value & 0xff)) {            s->configuration = (value & 0xff);            intf_update_required = 1;        }        goto do_request;    } else {    do_request:        ct.bRequestType = request >> 8;        ct.bRequest = request;        ct.wValue = value;        ct.wIndex = index;        ct.wLength = length;        ct.timeout = 50;        ct.data = data;        ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);    }    if (ret < 0) {        switch(errno) {        case ETIMEDOUT:            return USB_RET_NAK;        default:            return USB_RET_STALL;        }    } else {        if (intf_update_required) {#ifdef DEBUG            printf("usb_host_handle_control: updating interfaces\n");#endif            usb_host_update_interfaces(s, value & 0xff);        }        return ret;    }}static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p);static int usb_host_handle_data(USBDevice *dev, USBPacket *p){    USBHostDevice *s = (USBHostDevice *)dev;    struct usbdevfs_bulktransfer bt;    int ret;    uint8_t devep = p->devep;    if (s->endp_table[p->devep - 1].type == USBDEVFS_URB_TYPE_ISO) {        return usb_host_handle_isoch(dev, p);    }    /* XXX: optimize and handle all data types by looking at the       config descriptor */    if (p->pid == USB_TOKEN_IN)        devep |= 0x80;    bt.ep = devep;    bt.len = p->len;    bt.timeout = 50;    bt.data = p->data;    ret = ioctl(s->fd, USBDEVFS_BULK, &bt);    if (ret < 0) {        switch(errno) {        case ETIMEDOUT:            return USB_RET_NAK;        case EPIPE:        default:#ifdef DEBUG            printf("handle_data: errno=%d\n", errno);#endif            return USB_RET_STALL;        }    } else {        return ret;    }}#ifdef USE_ASYNCIOstatic void urb_completion_pipe_read(void *opaque){    USBHostDevice *s = opaque;    USBPacket *p = s->packet;    PendingURB *pending_urb = NULL;    struct usbdevfs_urb *purb = NULL;    int len, ret;    len = read(s->pipe_fds[0], &pending_urb, sizeof(pending_urb));    if (len != sizeof(pending_urb)) {        printf("urb_completion: error reading pending_urb, len=%d\n", len);        return;    }    /* FIXME: handle pending_urb->status */    del_pending_urb(pending_urb->urb);    if (!p) {        s->urbs_ready++;        return;    }    ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);    if (ret < 0) {        printf("urb_completion: REAPURBNDELAY ioctl=%d errno=%d\n",               ret, errno);        return;    }#ifdef DEBUG_ISOCH    if (purb == pending_urb->urb) {        printf("urb_completion: urb mismatch reaped=%p pending=%p\n",               purb, urb);    }#endif    p->len = purb->actual_length;    usb_packet_complete(p);    qemu_free(purb);    s->packet = NULL;}static void isoch_done(int signum, siginfo_t *info, void *context){    struct usbdevfs_urb *urb = (struct usbdevfs_urb *)info->si_addr;    USBHostDevice *s = (USBHostDevice *)urb->usercontext;    PendingURB *purb;    if (info->si_code != SI_ASYNCIO ||        info->si_signo != SIG_ISOCOMPLETE) {        return;    }    purb = get_pending_urb(urb);    if (purb) {        purb->status = info->si_errno;        write(s->pipe_fds[1], &purb, sizeof(purb));    }}#endifstatic int usb_host_handle_isoch(USBDevice *dev, USBPacket *p){    USBHostDevice *s = (USBHostDevice *)dev;    struct usbdevfs_urb *urb, *purb = NULL;    int ret;    uint8_t devep = p->devep;    if (p->pid == USB_TOKEN_IN)        devep |= 0x80;    urb = qemu_mallocz(sizeof(struct usbdevfs_urb) +                       sizeof(struct usbdevfs_iso_packet_desc));    if (!urb) {        printf("usb_host_handle_isoch: malloc failed\n");        return 0;    }    urb->type = USBDEVFS_URB_TYPE_ISO;    urb->endpoint = devep;    urb->status = 0;    urb->flags = USBDEVFS_URB_ISO_ASAP;    urb->buffer = p->data;    urb->buffer_length = p->len;    urb->actual_length = 0;    urb->start_frame = 0;    urb->error_count = 0;#ifdef USE_ASYNCIO    urb->signr = SIG_ISOCOMPLETE;#else    urb->signr = 0;#endif    urb->usercontext = s;    urb->number_of_packets = 1;    urb->iso_frame_desc[0].length = p->len;    urb->iso_frame_desc[0].actual_length = 0;    urb->iso_frame_desc[0].status = 0;    ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);    if (ret == 0) {        if (!add_pending_urb(urb)) {            printf("usb_host_handle_isoch: add_pending_urb failed %p\n", urb);        }    } else {        printf("usb_host_handle_isoch: SUBMITURB ioctl=%d errno=%d\n",               ret, errno);        qemu_free(urb);        switch(errno) {        case ETIMEDOUT:            return USB_RET_NAK;        case EPIPE:        default:            return USB_RET_STALL;        }    }#ifdef USE_ASYNCIO    /* FIXME: handle urbs_ready together with sync io     * workaround for injecting the signaled urbs into current frame */    if (s->urbs_ready > 0) {        ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);        if (ret == 0) {            ret = purb->actual_length;            qemu_free(purb);            s->urbs_ready--;        }        return ret;    }    s->packet = p;    return USB_RET_ASYNC;#else    ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);    if (ret == 0) {        if (del_pending_urb(purb)) {            ret = purb->actual_length;            qemu_free(purb);        } else {            printf("usb_host_handle_isoch: del_pending_urb failed %p\n", purb);        }    } else {#ifdef DEBUG_ISOCH        printf("usb_host_handle_isoch: REAPURBNDELAY ioctl=%d errno=%d\n",               ret, errno);#endif    }    return ret;#endif}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
99riav一区二区三区| 国产精一区二区三区| 久久国产婷婷国产香蕉| 91首页免费视频| 911精品产国品一二三产区| 国产欧美一区二区精品久导航| 一区二区三区免费观看| 国产电影一区二区三区| 欧美日韩一区二区在线观看| 国产精品免费人成网站| 久久99热99| 宅男噜噜噜66一区二区66| 一区二区在线观看免费视频播放| 国产精品小仙女| 欧美一级夜夜爽| 亚洲h精品动漫在线观看| 99精品在线免费| 中文字幕不卡在线| 国内精品伊人久久久久av一坑 | 日韩精品一区二区三区视频播放 | 粉嫩av一区二区三区粉嫩 | 国产精品欧美精品| 亚洲国产成人精品视频| 一本大道久久a久久综合| 中文字幕欧美区| 国产成人99久久亚洲综合精品| 91精品国产乱| 免费精品视频在线| 中文字幕视频一区| 高清不卡在线观看| 欧美极品xxx| 国产99久久久国产精品潘金网站| 精品va天堂亚洲国产| 国产在线一区二区综合免费视频| 日韩一区二区三区四区| 日韩成人一级大片| 欧美va日韩va| 国产乱妇无码大片在线观看| 久久久亚洲国产美女国产盗摄| 国内精品视频666| 久久久精品综合| 国产一区在线观看麻豆| 欧美久久久影院| 美女视频网站久久| 亚洲动漫第一页| 欧美日韩精品一区二区三区蜜桃| 亚洲高清免费观看| 欧美一区二区三区影视| 国产在线麻豆精品观看| 欧美国产综合色视频| 成人av免费观看| 亚洲一区日韩精品中文字幕| 欧美日韩三级在线| 黄色资源网久久资源365| 日本一区二区免费在线观看视频| heyzo一本久久综合| 亚洲一区在线观看视频| 精品日韩欧美一区二区| 4438x成人网最大色成网站| 青青草国产成人99久久| 国产欧美精品国产国产专区 | 青娱乐精品视频| 欧美日韩成人在线一区| 久久青草欧美一区二区三区| 成人免费av网站| 亚洲国产精品综合小说图片区| 日韩亚洲国产中文字幕欧美| 丁香啪啪综合成人亚洲小说| 亚洲一区免费观看| 26uuuu精品一区二区| 日本韩国一区二区| 国产伦精一区二区三区| 亚洲国产美女搞黄色| 久久影院午夜论| 欧美日韩中文一区| 成人app网站| 久久国产三级精品| 亚洲人精品午夜| 久久人人爽人人爽| 欧美精品粉嫩高潮一区二区| 高清在线不卡av| 蜜臀99久久精品久久久久久软件| 国产三级一区二区| 日韩一区二区三区观看| 色综合天天狠狠| 国产精品99久久不卡二区| 视频一区欧美精品| 一区二区三区四区在线| 久久久不卡网国产精品一区| 91精品国产欧美一区二区18| 色狠狠av一区二区三区| 成人av免费在线观看| 久久精品国产第一区二区三区| 夜夜揉揉日日人人青青一国产精品 | 91免费观看国产| 国产麻豆精品在线| 国产欧美日韩亚州综合 | 日韩欧美一区二区免费| 99久久免费视频.com| 国产一区免费电影| 麻豆高清免费国产一区| 日韩二区三区在线观看| 亚洲综合色网站| 怡红院av一区二区三区| 中文字幕中文字幕中文字幕亚洲无线| 26uuu久久天堂性欧美| 日韩欧美久久一区| 91精品国产综合久久久久| 欧美日韩久久一区二区| 欧美视频精品在线观看| 在线观看精品一区| 在线区一区二视频| 欧美午夜寂寞影院| 欧美日韩高清一区二区三区| 欧美在线free| 欧美精品在线观看一区二区| 欧美性色aⅴ视频一区日韩精品| 在线亚洲精品福利网址导航| 色噜噜久久综合| 欧美日韩国产综合一区二区三区| 欧美日韩在线观看一区二区 | 成人美女在线视频| 91啪亚洲精品| 欧美在线免费播放| 88在线观看91蜜桃国自产| 欧美高清视频www夜色资源网| 欧美老女人在线| 精品日产卡一卡二卡麻豆| 精品国产一区久久| 国产精品美女久久久久久久网站| 成人欧美一区二区三区在线播放| 中文字幕人成不卡一区| 一卡二卡欧美日韩| 美女网站在线免费欧美精品| 国产麻豆视频一区二区| 99久久综合99久久综合网站| 日本高清视频一区二区| 欧美欧美午夜aⅴ在线观看| 日韩欧美在线综合网| 中文字幕欧美激情| 亚洲成av人片一区二区三区| 久草精品在线观看| 99久久精品国产一区| 欧美精选在线播放| 日本一区二区三区四区在线视频 | 久久久激情视频| 亚洲日本丝袜连裤袜办公室| 亚洲国产精品久久久久秋霞影院| 久久99精品久久久久久国产越南 | 午夜亚洲国产au精品一区二区| 久久99日本精品| 97国产一区二区| 日韩一区二区免费在线电影| 中文字幕欧美三区| 国产综合久久久久久久久久久久| 中文字幕在线观看一区| 欧美极品另类videosde| 亚洲国产精品一区二区久久恐怖片| 精一区二区三区| 在线观看视频欧美| www欧美成人18+| 亚洲国产精品久久不卡毛片| 国产成a人亚洲| 91精品在线观看入口| 自拍偷拍亚洲综合| 国产一区二区成人久久免费影院 | 午夜视频在线观看一区二区| 国产精品资源在线观看| 欧美日韩高清不卡| 亚洲色图欧洲色图婷婷| 国产精品一品视频| 91精品国产综合久久精品app| 亚洲欧美怡红院| 国产福利精品导航| 日韩精品一区二区三区中文不卡| 亚洲黄色性网站| 成人va在线观看| 久久综合九色综合97婷婷| 午夜精品久久久久久久久| 91亚洲永久精品| 国产精品免费久久| 国产精品自在欧美一区| 精品日韩欧美在线| 日本午夜一区二区| 欧美日韩国产小视频| 亚洲精选在线视频| 99久久99久久精品免费看蜜桃| 2欧美一区二区三区在线观看视频| 午夜电影久久久| 欧美性做爰猛烈叫床潮| 亚洲一区二区偷拍精品| 色诱视频网站一区| 亚洲天堂中文字幕| www.日韩av| 亚洲欧洲国产日韩| 一本久久综合亚洲鲁鲁五月天| 国产精品视频一区二区三区不卡| 国产精品一区一区三区| 国产午夜精品一区二区| 国产成人免费网站|