亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
粉嫩高潮美女一区二区三区| www.成人网.com| 成人国产精品视频| 欧美日本精品一区二区三区| 国产日韩视频一区二区三区| 亚洲一卡二卡三卡四卡| 国产激情一区二区三区| 欧美性极品少妇| 中文字幕第一区二区| 蜜桃视频第一区免费观看| 91高清在线观看| 国产精品美女一区二区三区| 青青草国产成人99久久| 91在线视频播放地址| 久久免费视频一区| 日韩av一级电影| 欧美性大战xxxxx久久久| 亚洲国产精品v| 国产乱子轮精品视频| 日韩一区二区精品在线观看| 午夜影院久久久| 在线观看亚洲专区| 亚洲伦理在线精品| 一本一本大道香蕉久在线精品 | 91在线云播放| 国产精品高潮呻吟| 337p亚洲精品色噜噜狠狠| ㊣最新国产の精品bt伙计久久| 国产传媒欧美日韩成人| 久久美女高清视频| 国产精品一色哟哟哟| 久久免费看少妇高潮| 国产高清不卡一区| 精品欧美一区二区久久| 91成人免费网站| 99久久er热在这里只有精品66| 国产亚洲精品久| 国产成人免费视频网站高清观看视频| 精品乱码亚洲一区二区不卡| 久久爱另类一区二区小说| 欧美电影免费观看高清完整版在 | 日韩欧美一级在线播放| 天天免费综合色| 91免费在线视频观看| 亚洲精品成人a在线观看| 欧美午夜电影网| 午夜激情久久久| 日韩精品专区在线影院重磅| 国产在线精品一区二区夜色| 欧美激情一区在线观看| 99久久婷婷国产综合精品电影| 亚洲男同性恋视频| 666欧美在线视频| 麻豆国产精品官网| 久久久国产精品午夜一区ai换脸| 国产99久久久国产精品潘金网站| 国产精品国产三级国产普通话三级| 色婷婷综合五月| 首页国产欧美久久| 国产欧美精品国产国产专区| 91视频国产观看| 蜜臀av国产精品久久久久| 日韩激情视频网站| 久久蜜桃一区二区| 欧美丝袜丝交足nylons| 精品一区二区在线播放| 亚洲人妖av一区二区| 欧美一区二区三区系列电影| 成人午夜免费av| 天堂资源在线中文精品| 日本一区二区综合亚洲| 欧美视频在线一区| 成人午夜视频在线| 天天av天天翘天天综合网色鬼国产| 2022国产精品视频| 在线观看三级视频欧美| 韩国成人在线视频| 亚洲高清视频的网址| 国产欧美一区二区三区沐欲| 欧美日韩国产成人在线免费| 成人性生交大片免费看视频在线| 亚洲h精品动漫在线观看| 欧美国产综合一区二区| 3d动漫精品啪啪一区二区竹菊| 99久久国产免费看| 国产精品自拍在线| 蜜桃精品在线观看| 亚洲一区二区在线观看视频| 国产精品欧美一区二区三区| 日韩午夜小视频| 欧美猛男超大videosgay| a在线欧美一区| 国产成人亚洲综合a∨婷婷| 日韩国产在线观看一区| 亚洲一区中文在线| 综合色中文字幕| 国产精品久久一级| 久久精品人人做人人综合| 日韩精品一区二区三区四区视频| 欧美系列日韩一区| 欧美在线视频日韩| 91蝌蚪国产九色| 99久久精品情趣| 成人久久久精品乱码一区二区三区| 久久99精品网久久| 久久国产精品99精品国产| 丝袜美腿亚洲综合| 丝袜美腿亚洲色图| 丝袜美腿高跟呻吟高潮一区| 亚洲国产精品欧美一二99| 一区二区免费视频| 一区二区不卡在线视频 午夜欧美不卡在| 国产精品午夜久久| 国产精品毛片无遮挡高清| 欧美国产日韩亚洲一区| 国产精品入口麻豆九色| 中文字幕一区二区三区视频| 国产精品国产三级国产aⅴ入口| 国产精品美女久久久久久久| 国产精品传媒视频| 亚洲欧美偷拍卡通变态| 亚洲一区电影777| 性久久久久久久久久久久| 免费人成在线不卡| 看片的网站亚洲| 国产精品一区二区视频| 成人精品在线视频观看| 色乱码一区二区三区88| 欧美精品视频www在线观看| 日韩一级片在线播放| 精品国产区一区| 日本一区二区三区免费乱视频| 中文子幕无线码一区tr| 亚洲激情自拍视频| 日本中文一区二区三区| 久久99国内精品| 成人激情图片网| 在线观看一区二区精品视频| 欧美一级日韩一级| 国产三区在线成人av| 亚洲人亚洲人成电影网站色| 丝袜脚交一区二区| 国产成人精品午夜视频免费| 99久久精品99国产精品| 欧美精品视频www在线观看| 久久免费精品国产久精品久久久久| 国产精品久久久久一区二区三区共| 亚洲黄网站在线观看| 免费精品99久久国产综合精品| 国产99精品国产| 欧美伦理影视网| 欧美国产视频在线| 日韩精品乱码免费| 成人app在线| 日韩欧美中文一区二区| 亚洲图片另类小说| 久久99久久精品| 色网综合在线观看| 久久久久综合网| 午夜国产精品影院在线观看| 懂色一区二区三区免费观看| 777a∨成人精品桃花网| 中文字幕精品在线不卡| 免费看日韩a级影片| 91视频91自| 久久精品夜色噜噜亚洲a∨| 亚洲成人综合网站| 成人av在线网站| 精品国产91乱码一区二区三区| 亚洲激情图片qvod| 成人禁用看黄a在线| 精品久久久久久最新网址| 一区二区三区成人| 成人av电影在线播放| 国产亚洲午夜高清国产拍精品| 丝袜a∨在线一区二区三区不卡| a4yy欧美一区二区三区| 国产色婷婷亚洲99精品小说| 奇米色一区二区| 欧美日本免费一区二区三区| 亚洲免费三区一区二区| www.久久久久久久久| 久久精品亚洲麻豆av一区二区| 免费在线欧美视频| 欧美精品久久久久久久多人混战| 亚洲欧美日韩在线不卡| 成人小视频免费在线观看| 精品1区2区在线观看| 免费视频最近日韩| 91精品国产综合久久久久久| 一区二区三区高清不卡| 91高清视频免费看| 亚洲美女一区二区三区| 99精品视频在线观看| 最近中文字幕一区二区三区| 成人福利在线看| 国产精品免费看片| av中文一区二区三区| 亚洲欧美一区二区在线观看| 成人激情午夜影院|