中文字幕 另类精品,亚洲欧美一区二区蜜桃,日本在线精品视频免费,孩交精品乱子片免费

<sup id="3hn2b"></sup>

    1. <sub id="3hn2b"><ol id="3hn2b"></ol></sub><legend id="3hn2b"></legend>

      1. <xmp id="3hn2b"></xmp>

      2. 新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Linux USB gadget設(shè)備驅(qū)動(dòng)解析(4)--編寫一個(gè)gadget驅(qū)動(dòng)

        Linux USB gadget設(shè)備驅(qū)動(dòng)解析(4)--編寫一個(gè)gadget驅(qū)動(dòng)

        作者: 時(shí)間:2012-08-06 來(lái)源:網(wǎng)絡(luò) 收藏

        .bmAttributes = _ENDPOINT_XFER_BULK,

        };

        static struct usb_config_descriptor loopback_config = { //配置描述符

        .bLength = sizeof loopback_config,

        .bDescriptorType = _DT_CONFIG,

        /* compute wTotalLength on the fly */

        .bNumInterfaces = 1,

        .bConfigurationValue = CONFIG_LOOPBACK,

        .iConfiguration = STRING_LOOPBACK,

        .bmAttributes = _CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFpower,

        .bMaxPower = 1, /* self-powered */

        };

        static const struct usb_interface_descriptor loopback_intf = { //接口描述符

        .bLength = sizeof loopback_intf,

        .bDescriptorType = USB_DT_INTERFACE,

        .bNumEndpoints = 1,

        .bInterfaceClass = USB_CLASS_VENDOR_SPEC,

        .iInterface = STRING_LOOPBACK,

        };

        /* static strings, in UTF-8 */

        #define STRING_MANUFACTURER 25

        #define STRING_PRODUCT 42

        #define STRING_SERIAL 101

        #define STRING_SOURCE_SINK 250

        #define STRING_LOOPBACK 251

        static char manufacturer[50];

        /* default serial number takes at least two packets */

        static char serial[] = 0123456789.0123456789.0123456789;

        static struct usb_string strings[] = { //字符串描述符

        { STRING_MANUFACTURER, manufacturer, },

        { STRING_PRODUCT, longname, },

        { STRING_SERIAL, serial, },

        { STRING_LOOPBACK, loopback, },

        { STRING_SOURCE_SINK, source_sink, },

        { } /* end of list */

        };

        static struct usb__strings stringtab = {

        .language = 0x0409, /* en-us */

        .strings = strings,

        };

        static const struct usb_descriptor_header *fs_loopback_function[] = {

        (struct usb_descriptor_header *) loopback_intf,

        (struct usb_descriptor_header *) fs_sink_desc,

        NULL,

        };

        static int

        usb_zero_open (struct inode *inode, struct file *file) //打開(kāi)設(shè)備

        {

        struct zero_dev *dev =

        container_of (inode->i_cdev, struct zero_dev, cdev);

        file->private_data = dev;

        init_waitqueue_head (dev->bulkrq);

        return 0;

        }

        static int

        usb_zero_release (struct inode *inode, struct file *file) //關(guān)閉設(shè)備

        {

        return 0;

        }

        static void free_ep_req(struct usb_ep *ep, struct usb_request *req)

        {

        kfree(req->buf);

        usb_ep_free_request(ep, req);

        }

        static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)//分配請(qǐng)求

        {

        struct usb_request *req;

        req = usb_ep_alloc_request(ep, GFP_ATOMIC);

        if (req) {

        req->length = length;

        req->buf = kmalloc(length, GFP_ATOMIC);

        if (!req->buf) {

        usb_ep_free_request(ep, req);

        req = NULL;

        }

        }

        return req;

        }

        static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)//請(qǐng)求完成函數(shù)

        {

        struct zero_dev *dev = ep->driver_data;

        int status = req->status;

        switch (status) {

        case 0: /* normal completion */

        if (ep == dev->out_ep) {

        memcpy(dev->data, req->buf, req-> actual);//返回?cái)?shù)據(jù)拷貝到req->buf中, //dev->data_size=req->length;

        dev->data_size=req->actual; //實(shí)際長(zhǎng)度為req-> actual;需要確認(rèn)

        req –>short_not_ok為0。參考.h中關(guān)于usb_request結(jié)構(gòu)的注釋

        }

        break;

        /* this endpoint is normally active while we're configured */

        case -ECONNABORTED: /* hardware forced ep reset */

        case -ECONNRESET: /* request dequeued */

        case -ESHUTDOWN: /* disconnect from host */

        printk(%s gone (%d), %d/%dn, ep->name, status,

        req->actual, req->length);

        case -EOVERFLOW: /* buffer overrun on read means that

        * we didn't provide a big enough

        * buffer.

        */

        default:

        #if 1

        printk(%s complete --> %d, %d/%dn, ep->name,

        status, req->actual, req->length);

        #endif

        case -EREMOTEIO: /* short read */

        break;

        }

        free_ep_req(ep, req);

        wake_up_interruptible (dev->bulkrq); //喚醒讀函數(shù)

        }

        static struct usb_request *source_sink_start_ep(struct usb_ep *ep)//構(gòu)造并發(fā)送讀請(qǐng)求

        {

        struct usb_request *req;

        int status;

        //printk(in %sn,__FUNCTION__);

        req = alloc_ep_req(ep, 128);

        if (!req)

        return NULL;

        memset(req->buf, 0, req->length);

        req->complete = source_sink_complete; //請(qǐng)求完成函數(shù)

        status = usb_ep_queue(ep, req, GFP_ATOMIC); //遞交請(qǐng)求

        if (status) {

        struct zero_dev *dev = ep->driver_data;

        printk(start %s --> %dn, ep->name, status);

        free_ep_req(ep, req);

        req = NULL;

        }

        linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

        linux相關(guān)文章:linux教程




        評(píng)論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉