• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

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

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

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

    value = min(w_length, (u16) sizeof device_desc);

    memcpy(req->buf, device_desc, value);

    break;

    case _DT_CONFIG: //獲取配置,注意:會根據(jù)fs_loopback_function讀取到接口、端點描述符,注意通過config_buf完成讀取數(shù)據(jù)及數(shù)量的統(tǒng)計。

    value = config_buf(, req->buf,

    w_value >> 8,

    w_value 0xff);

    if (value >= 0)

    value = min(w_length, (u16) value);

    break;

    case _DT_STRING:

    value = usb__get_string(stringtab,

    w_value 0xff, req->buf);

    if (value >= 0)

    value = min(w_length, (u16) value);

    break;

    }

    break;

    case _REQ_SET_CONFIGURATION:

    if (ctrl->bRequestType != 0)

    goto unknown;

    spin_lock(dev->lock);

    value = zero_set_config(dev, w_value);//激活相應(yīng)的端點

    spin_unlock(dev->lock);

    break;

    default:

    unknown:

    printk(

    unknown control req%02x.%02x v%04x i%04x l%dn,

    ctrl->bRequestType, ctrl->bRequest,

    w_value, w_index, w_length);

    }

    /* respond with data transfer before status phase */

    if (value >= 0) {

    req->length = value;

    req->zero = value w_length;

    value = usb_ep_queue(->ep0, req, GFP_ATOMIC);//通過端點0完成setup

    if (value 0) {

    printk(ep_queue --> %dn, value);

    req->status = 0;

    zero_setup_complete(gadget->ep0, req);

    }

    }

    /* device either stalls (value 0) or reports success */

    return value;

    }

    static void zero_unbind(struct usb_gadget *gadget) //解除綁定

    {

    struct zero_dev *dev = get_gadget_data(gadget);

    printk(unbindn);

    unregister_chrdev_region (MKDEV (usb_zero_major, 0), 1);

    cdev_del ((dev->cdev));

    /* we've already been disconnected ... no i/o is active */

    if (dev->req) {

    dev->req->length = USB_BUFSIZ;

    free_ep_req(gadget->ep0, dev->req);

    }

    kfree(dev);

    set_gadget_data(gadget, NULL);

    }

    static int __init zero_bind(struct usb_gadget *gadget) //綁定過程

    {

    struct zero_dev *dev;

    struct usb_ep *ep;

    int gcnum;

    usb_ep_autoconfig_reset(gadget);

    ep = usb_ep_autoconfig(gadget, fs_sink_desc);//根據(jù)端點描述符及控制器端點情況,分配合適的端點。

    if (!ep)

    goto enomem;

    EP_OUT_NAME = ep->name; //記錄名稱

    gcnum = usb_gadget_controller_number(gadget);//獲得控制器代號

    if (gcnum >= 0)

    device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);//賦值設(shè)備描述符

    else {

    pr_warning(%s: controller '%s' not recognizedn,

    shortname, gadget->name);

    device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);

    }

    dev = kzalloc(sizeof(*dev), GFP_KERNEL); //分配設(shè)備結(jié)構(gòu)體

    if (!dev)

    return -ENOMEM;

    spin_lock_init(dev->lock);

    dev->gadget = gadget;

    set_gadget_data(gadget, dev);

    dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);//分配請求

    if (!dev->req)

    goto enomem;

    dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL);

    if (!dev->req->buf)

    goto enomem;

    dev->req->complete = zero_setup_complete;

    dev->out_ep=ep; //記錄端點(就是接收host端數(shù)據(jù)的端點)

    printk(name=%sn,dev->out_ep->name); //打印出這個端點的名稱

    ep->driver_data=dev;

    device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;

    usb_gadget_set_selfpowered(gadget);

    gadget->ep0->driver_data = dev;

    snprintf(manufacturer, sizeof manufacturer, %s %s with %s,

    init_utsname()->sysname, init_utsname()->release,

    gadget->name);

    /**************************字符設(shè)備注冊*******************/

    dev_t usb_zero_dev = MKDEV (usb_zero_major, 0);

    int result = register_chrdev_region (usb_zero_dev, 1, usb_zero);

    if (result 0)

    {

    printk (KERN_NOTICE Unable to get usb_transfer region, error %dn,result);

    return 0;

    }

    usb_zero_setup_cdev (dev, 0);

    return 0;

    enomem:

    zero_unbind(gadget);

    return -ENOMEM;

    }

    /*-------------------------------------------------------------------------*/

    static struct usb_gadget_driver zero_driver = { //gadget的核心數(shù)據(jù)結(jié)構(gòu)

    #ifdef CONFIG_USB_GADGET_DUALSPEED

    .speed = USB_SPEED_HIGH,

    #else

    .speed = USB_SPEED_FULL,

    #endif

    .function = (char *) longname,

    .bind = zero_bind,

    .unbind = __exit_p(zero_unbind),

    .setup = zero_setup,

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

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




    評論


    相關(guān)推薦

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

    關(guān)閉
    主站蜘蛛池模板: 二连浩特市| 江都市| 句容市| 兴义市| 孟村| 来凤县| 东乡族自治县| 和龙市| 天气| 四会市| 探索| 定兴县| 宣恩县| 青海省| 通化县| 苏州市| 宁远县| 乃东县| 双牌县| 秭归县| 铁岭市| 英超| 南召县| 阿坝| 巩留县| 富源县| 拉萨市| 东阳市| 临湘市| 托克逊县| 永泰县| 昌邑市| 武鸣县| 耒阳市| 山阴县| 房山区| 白银市| 奉贤区| 义马市| 黄浦区| 高州市|