Linux那些事儿之我是EHCI(4) data structure of ehci driver and device

阿扁"辞职"了,kde4发布了,更让我激动的是,英雄志过两天又有更新了,这部连载长达8年的小说,终于要进入精彩的大结局。卢云的命运究竟如何?观海云远,四个性格理念完全不同的人,谁是好,谁是坏,谁是对,谁是错?何谓正道? 接着上回说,usb_hcd_pci_probe这个函数在"我是UHCI"中也有讨论,不过我想按照我的思路写下去。 46 /**//** 47 * usb_hcd_pci_probe - initialize PCI-based HCDs 48 * @dev: USB Host Controller being probed 49 * @id: pci hotplug id connecting controller to HCD framework 50 * Context: !in_interrupt() 51 * 52 * Allocates basic PCI resources for this USB host controller, and 53 * then invokes the start() method for the HCD associated with it 54 * through the hotplug entry's driver_data. 55 * 56 * Store this function in the HCD's struct pci_driver as probe(). 57 */ 58 int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) 59 ...{ 60 struct hc_driver *driver; 61 struct usb_hcd *hcd; 62 int retval; 63 64 if (usb_disabled()) 65 return -ENODEV; 66 67 if (!id || !(driver = (struct hc_driver *) id->driver_data)) 68 return -EINVAL; 69 70 if (pci_enable_device (dev) < 0) 71 return -ENODEV; 72 dev->current_state = PCI_D0; 73 dev->dev.power.power_state = PMSG_ON; 74 75 if (!dev->irq) ...{ 76 dev_err (&dev->dev, 77 "Found HC with no IRQ. Check BIOS/PCI %s setup! ", 78 pci_name(dev)); 79 retval = -ENODEV; 80 goto err1; 81 } 82 83 hcd = usb_create_hcd (driver, &dev->dev, pci_name(dev)); 84 if (!hcd) ...{ 85 retval = -ENOMEM; 86 goto err1; 87 } 88 89 if (driver->flags & HCD_MEMORY) ...{ // EHCI, OHCI 90 hcd->rsrc_start = pci_resource_start (dev, 0); 91 hcd->rsrc_len = pci_resource_len (dev, 0); 92 if (!request_mem_region (hcd->rsrc_start, hcd->rsrc_len, 93 driver->description)) ...{ 94 dev_dbg (&dev->dev, "controller already in use "); 95 retval = -EBUSY; 96 goto err2; 97 } 98 hcd->regs = ioremap_nocache (hcd->rsrc_start, hcd->rsrc_len); 99 if (hcd->regs == NULL) ...{ 100 dev_dbg (&dev->dev, "error mapping memory "); 101 retval = -EFAULT; 102 goto err3; 103 } 104 105 } else ...{ // UHCI 106 int region; 107 108 for (region = 0; region < PCI_ROM_RESOURCE; region++) ...{ 109 if (!(pci_resource_flags (dev, region) & 110 IORESOURCE_IO)) 111 continue; 112 113 hcd->rsrc_start = pci_resource_start (dev, region); 114 hcd->rsrc_len = pci_resource_len (dev, region); 115 if (request_region (hcd->rsrc_start, hcd->rsrc_len, 116 driver->description)) 117 break; 118 } 119 if (region == PCI_ROM_RESOURCE) ...{ 120 dev_dbg (&dev->dev, "no i/o regions available "); 121 retval = -EBUSY; 122 goto err1; 123 } 124 } 125 126 pci_set_master (dev); 127 128 retval = usb_add_hcd (hcd, dev->irq, IRQF_SHARED); 129 if (retval != 0) 130 goto err4; 131 return retval; 132 133 err4: 134 if (driver->flags & HCD_MEMORY) ...{ 135 iounmap (hcd->regs); 136 err3: 137 release_mem_region (hcd->rsrc_start, hcd->rsrc_len); 138 } else 139 release_region (hcd->rsrc_start, hcd->rsrc_len); 140 err2: 141 usb_put_hcd (hcd); 142 err1: 143 pci_disable_device (dev); 144 dev_err (&dev->dev, "init %s fail, %d ", pci_name(dev), retval); 145 return retval; 146 } 64行,usb_disabled()判断内核有没有开启支持usb,要是这都不支持,一切都免谈。 70行,pci_enable_device()这是对ehci三类接口中的pci configuration space进行操作,设置其中某个寄存器的值,使设备处于工作状态。调用pci_read_config_word()和pci_write_config_word来读写pci配置空间的寄存器。pci_enable_device -> pci_enable_device_bars -> do_pci_enable_device ... 原理不难,只要对照spec可以看懂。 72,73是电源管理的内容。75判断设备的中断号是否为空。 83,usb_create_hcd() 创建一个usb_hcd机构体。 1480 /**//** 1481 * usb_create_hcd - create and initialize an HCD structure 1482 * @driver: HC driver that will use this hcd 1483 * @dev: device for this HC, stored in hcd->self.controller 1484 * @bus_name: value to store in hcd->self.bus_name 1485 * Context: !in_interrupt() 1486 * 1487 * Allocate a struct usb_hcd, with extra space at the end for the 1488 * HC driver's private data. Initialize the generic members of the 1489 * hcd structure. 1490 * 1491 * If memory is unavailable, returns NULL. 1492 */ 1493 struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, 1494 struct device *dev, char *bus_name) 1495 ...{ 1496 struct usb_hcd *hcd; 1497 1498 hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL); 1499 if (!hcd) ...{ 1500 dev_dbg (dev, "hcd alloc failed "); 1501 return NULL; 1502 } 1503 dev_set_drvdata(dev, hcd); 1504 kref_init(&hcd->kref); 1505 1506 usb_bus_init(&hcd->self); 1507 hcd->self.controller = dev; 1508 hcd->self.bus_name = bus_name; 1509 hcd->self.uses_dma = (dev->dma_mask != NULL); 1510 1511 init_timer(&hcd->rh_timer); 1512 hcd->rh_timer.function = rh_timer_func; 1513 hcd->rh_timer.data = (unsigned long) hcd; 1514 #ifdef CONFIG_PM 1515 INIT_WORK(&hcd->wakeup_work, hcd_resume_work); 1516 #endif 1517 1518 hcd->driver = driver; 1519 hcd->product_desc = (driver->product_desc) ? driver->product_desc : 1520 "USB Host Controller"; 1521 1522 return hcd; 1523 } 一下子出现了很多数据结构,现在有必要捋一捋它们之间的关系。 (1)描述驱动的数据结构 ehci主控器的驱动程序需要包括些什么东西?站在pci总线的角度来说,ehci是一个pci的设备,驱动程序里面必须提供操作ehci设备,比如开启(start),关闭(stop),重启(reset),中断的函数。另外,站在usb控制器的角度来说,驱动程序里面还要与底层usb系统交互的函数,如插入/删除urb(rb_enqueue, urb_dequeue)。 pci_driver ehci_pci_driver{ ......... .id_table = pci_ids, ------------>driver_data = (unsigned long) &ehci_pci_hc_driver, .probe = usb_hcd_pci_probe } hc_driver ehci_pci_hc_driver{ ........ .hcd_priv_size = sizeof(struct ehci_hcd), .irq = ehci_irq, .reset = ehci_pci_setup, .start = ehci_run, .stop = ehci_stop, .shutdown = ehci_shutdown, .urb_enqueue = ehci_urb_enqueue, .urb_dequeue = ehci_urb_dequeue, } (2)描述设备的数据结构 usb_hcd{ ........ usb_bus .self .hcd_priv = ehci_hcd } usb_hcd交大人甲有过论述:linux那些事儿 之 戏说USB(28)设备的生命线 (七) http://blog.csdn.net/fudan_abc/archive/2007/10/18/1831459.aspx usb_hcd注释上说USB Host Controller Driver,但我更愿意认为它是一个描述一个usb主控制器设备的数据结构。usb_hcd描述了usb主控制器共有的属性,usb_hcd.hcd_priv指向了特定的主控制器数据结构,它描述各自特有的属性。对ehci,是ehci_hcd,对uhci,是 uhci_hcd。usb_hcd的成员usb_bus self 是HCD bus-glue layer,usb主控器与总线之间粘合剂。 这样,1498就好理解了。1506行usb_bus_init初始化usb_hcd.self。 1511-1513初始化 root harbor 计时器。然后就有返回到usb_hcd_pci_probe()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值