int xhci_plat_probe之见解

来源:互联网 发布:全国软件开发考试报名 编辑:程序博客网 时间:2024/05/21 17:35
/*
 * 在xhci_plat_probe里,两个重量级的函数是usb_create_hcd和usb_add_hcd,
 * 用了创建usb_hcd和将usb_hcd添加到系统中。
 * 在这里,有两个usb_hcd,一个是main_hcd(或者primary_hcd),一个是shared_hcd。
 * hc_driver中的reset函数对应为xhci_plat_setup,其调用的xhci_gen_setup有如下一段。
 * 原来xhci为了向下兼容,集成了两个roothub,一个对应usb2.0(main_hcd),一个对应usb3.0及以上(shared_hcd)。
 * 怎么区分usb2.0的端口和usb3.0的端口呢?xhci extended capabilities里有:7.2 xHCI Supported Protocol Capability
 * 对应的代码在xhci_mem_init里,请读者自行分析.
 */
static int xhci_plat_probe(struct platform_device *pdev)
{
const struct hc_driver*driver;
struct xhci_hcd*xhci;
struct resource         *res;
struct usb_hcd*hcd;
int ret;
int irq;


if (usb_disabled())
return -ENODEV;


driver = &xhci_plat_xhci_driver;


irq = platform_get_irq(pdev, 0);
if (irq < 0)
return -ENODEV;


res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;


hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd)
return -ENOMEM;


hcd->rsrc_start = res->start;
hcd->rsrc_len = resource_size(res);


if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
driver->description)) {
dev_dbg(&pdev->dev, "controller already in use\n");
ret = -EBUSY;
goto put_hcd;
}


hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
if (!hcd->regs) {
dev_dbg(&pdev->dev, "error mapping memory\n");
ret = -EFAULT;
goto release_mem_region;
}


ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (ret)
goto unmap_registers;


/* USB 2.0 roothub is stored in the platform_device now. */
hcd = dev_get_drvdata(&pdev->dev);
xhci = hcd_to_xhci(hcd);
xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev,
dev_name(&pdev->dev), hcd);
if (!xhci->shared_hcd) {
ret = -ENOMEM;
goto dealloc_usb2_hcd;
}


/*
* Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
* is called by usb_add_hcd().
*/
*((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;


ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
if (ret)
goto put_usb3_hcd;


return 0;


put_usb3_hcd:
usb_put_hcd(xhci->shared_hcd);


dealloc_usb2_hcd:
usb_remove_hcd(hcd);


unmap_registers:
iounmap(hcd->regs);


release_mem_region:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);


put_hcd:
usb_put_hcd(hcd);


return ret;
}
原创粉丝点击