Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1569627
  • 博文数量: 204
  • 博客积分: 2215
  • 博客等级: 大尉
  • 技术积分: 4426
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-06 08:03
个人简介

气质,源于心灵的自信!

文章存档

2018年(1)

2017年(1)

2016年(1)

2015年(18)

2014年(20)

2013年(30)

2012年(119)

2011年(14)

分类: LINUX

2012-09-07 15:38:37

static struct platform_driver ehci_msm_driver = {
    .probe    = ehci_msm_probe,
    .remove    = __exit_p(ehci_msm_remove),
    .driver    = {.name = "msm_hsusb_host",
            .pm = &ehci_msm_dev_pm_ops, },
};
ehci_msm_probe(struct platform_device *pdev)
     msm_xusb_init_host(pdev, mhcd);
        otg_set_host(mhcd->xceiv, &hcd->self);
            otg->set_host(otg, host);
                msm_otg_set_host(struct otg_transceiver *xceiv, struct usb_bus *host)
                        dev->usbdev_nb.notifier_call = usbdev_notify;//挂载通知函数
                        usb_register_notify(&dev->usbdev_nb);//注册通知链
                        queue_work(dev->wq, &dev->sm_work);//驱动otg状态机
//--------------------------------------------------------------------------------------------------------
//下面看下通知函数
static int usbdev_notify(struct notifier_block *self,unsigned long action, void *device)
{
    enum usb_otg_state state;
    struct msm_otg *dev = container_of(self, struct msm_otg, usbdev_nb);
    struct usb_device *udev = device;
    int work = 1;
    unsigned long flags;

    if (!udev->parent || udev->parent->parent)//直接插入hub中
        goto out;

    spin_lock_irqsave(&dev->lock, flags);
    state = dev->otg.state;//取出当前otg状态
    spin_unlock_irqrestore(&dev->lock, flags);

    switch (state) {
    case OTG_STATE_A_WAIT_BCON:
        if (action == USB_DEVICE_ADD) {
            pr_debug("B_CONN set\n");
            set_bit(B_CONN, &dev->inputs);//改变位域的值
            if (udev->actconfig) {
                set_aca_bmaxpower(dev,udev->actconfig->desc.bMaxPower * 2);
                goto do_work;
            }
            if (udev->portnum == udev->bus->otg_port)
                set_aca_bmaxpower(dev, USB_IB_UNCFG);
            else
                set_aca_bmaxpower(dev, 100);
        }
        break;
    case OTG_STATE_A_HOST:
        if (action == USB_DEVICE_REMOVE) {
            pr_debug("B_CONN clear\n");
            clear_bit(B_CONN, &dev->inputs);//改变位域的值
            set_aca_bmaxpower(dev, 0);
        }
        break;
    default:
        work = 0;
        break;
    }
do_work:
    if (work) {
        wake_lock(&dev->wlock);
        queue_work(dev->wq, &dev->sm_work);//调度work,驱动otg状态机
    }
out:
    return NOTIFY_OK;
}
//下面是该通知链调用的时机
static int generic_probe(struct usb_device *udev)
{
    ................
    /* USB device state == configured ... usable */
    usb_notify_add_device(udev);//调用通知链函数

    return 0;
}
阅读(3127) | 评论(0) | 转发(10) |
给主人留下些什么吧!~~