• OSK USB 驱动


    USB驱动与设备
    1. 在嵌入式设备中使用platform总线

    #define PLATFORM_DRIVER    platform_driver_rtl8672
    struct platform_driver platform_driver_rtl8672 = {
    .probe = ehci_rtl8672_drv_probe,
    #ifdef CONFIG_HOTPLUG
    .remove = ehci_rtl8672_drv_remove,
    #endif
    .shutdown = usb_hcd_platform_shutdown,
    .driver = {
    .name = "rtl8672-ehci",
    },
    };
    static struct platform_device rtl8672_ehci = {
    .name = "rtl8672-ehci",
    .id = 0,
    .dev = {
    .release = usb_release,
    .dma_mask = (void *)~0,
    //.coherent_dma_mask = ~0,
    },
    .num_resources = ARRAY_SIZE(rtl8672_ehci_resources),
    .resource = rtl8672_ehci_resources, /* 定义了中断号及寄存器地址等. */
    };

    int __init ehci_hcd_init(void)
    {
    int retval = 0;

    retval = platform_driver_register(&PLATFORM_DRIVER);
    if (retval < 0)
    return retval;

    retval = platform_device_register(&rtl8672_ehci);

    return retval;
    }

    /*
     * platform的驱动和设备使用简单匹配, 只比较驱动和设备的name是否一样. 如上面的"rtl8672-ehci".
     */
    1. 怎样找到U盘的驱动程序呢?
    当U盘插入到USB口时, hub_port_connect_change()函数被调用, 注意最后有一个usb_new_device(), 这里
    将会调用usb_probe_interface(), 此函数由usb_register_driver注册的, 即usb_stor_register(&usb_stor_driver)
    ->usb_register->usb_register_driver.

    /* Handle physical or logical connection change events.
    * This routine is called when:
    * a port connection-change occurs;
    * a port enable-change occurs (often caused by EMI);
    * usb_reset_device() encounters changed descriptors (as from
    * a firmware download)
    * caller already locked the hub
    */
    static void hub_port_connect_change(struct usb_hub *hub, int port1,
    u16 portstatus, u16 portchange)
    {
    // 精简版, 去除了错误处理 :-)
    for (i = 0; i < SET_CONFIG_TRIES; i++) { /* 最大重试次数 */
    struct usb_device *udev;

    /* reallocate for each attempt, since references
    * to the previous one can escape in various ways
    */
    udev = usb_alloc_dev(hdev, hdev->bus, port1);
    usb_set_device_state(udev, USB_STATE_POWERED);
    /* set the address */
    choose_address(udev);
    /* reset and get descriptor */
    status = hub_port_init(hub, udev, port1, i);

    /* check for devices running slower than they could */
    if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200
    && udev->speed == USB_SPEED_FULL
    && highspeed_hubs != 0)
    check_highspeed (hub, udev, port1);

    /* Run it through the hoops (find a driver, etc) */
    if (!status) {
    status = usb_new_device(udev);
    if (status) {
    spin_lock_irq(&device_state_lock);
    hdev->children[port1-1] = NULL;
    spin_unlock_irq(&device_state_lock);
    }
    }

    status = hub_power_remaining(hub);
    return;
    }
    }

    /* called from driver core with dev locked */
    static int usb_probe_interface(struct device *dev)
    {
    struct usb_driver *driver = to_usb_driver(dev->driver);
    struct usb_interface *intf;
    struct usb_device *udev;
    const struct usb_device_id *id;
    int error = -ENODEV;

    if (is_usb_device(dev)) /* Sanity check */
    return error;

    intf = to_usb_interface(dev);
    udev = interface_to_usbdev(intf);

    id = usb_match_id(intf, driver->id_table);
    if (!id)
    id = usb_match_dynamic_id(intf, driver);
    if (id) {
    usb_autoresume_device(udev, 1);
    /* Interface "power state" doesn't correspond to any hardware
    * state whatsoever. We use it to record when it's bound to
    * a driver that may start I/0: it's not frozen/quiesced.
    */
    mark_active(intf);
    intf->condition = USB_INTERFACE_BINDING;

    /* The interface should always appear to be in use
    * unless the driver suports autosuspend.
    */
    intf->pm_usage_cnt = !(driver->supports_autosuspend);

    error = driver->probe(intf, id);
    if (error) {
    mark_quiesced(intf);
    intf->needs_remote_wakeup = 0;
    intf->condition = USB_INTERFACE_UNBOUND;
    } else
    intf->condition = USB_INTERFACE_BOUND;

    usb_autosuspend_device(udev, 1);
    }

    return error;
    }






  • 相关阅读:
    Android中ProgressDialog的应用
    Content的startActivity方法需添加FLAG_ACTIVITY_NEW_TASK flag
    android onKeydown
    8 个最优秀的 Android Studio 插件
    Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
    Android提供的LruCache类简介
    Android设计中的.9.png与Android Studio中的设置
    js实现双击后网页自己主动跑-------Day55
    Oracle经常使用函数
    《R实战》读书笔记三
  • 原文地址:https://www.cnblogs.com/codestub/p/2285446.html
Copyright © 2020-2023  润新知