现在的位置: 首页 > 综合 > 正文

Linux那些事儿 之 戏说USB(22)设备的生命线(一)

2013年08月10日 ⁄ 综合 ⁄ 共 3793字 ⁄ 字号 评论关闭

李安告诉我们,每个人的心中都有一座断背山,每个人的手里都有一条生命线。

Google一下,找到这么一句:通常生命线都起自姆指和食指的中央,如果比这个位置还要上方的人,主进取心和克已心都很强,只要奋斗努力,事业终有可成。再仔细看看自己的手,果然位于姆指与食指的中间靠上08微米,也算是搭了个08年奥运的好兆头,继海南那个万里长跑迎奥运的小女孩儿之后,俺也终于有了奥运题材,有了乐观的理由。什么叫乐观派的人?这个就像茶壶一样,屁股都烧的红红的,他还有心情吹口哨。俺可不想做茶壶,还是赶紧的言归正传吧。

BH的人生有BH的活法,设备的人生有设备的过法。设备也有它自己的生命线,自你把它插到hub上始,自你把它从hub上拔下来终,它的一生是勤勉努力、朴实无华的一生,它的一生是埋头苦干、默默奉献的一生。BH的人生不需要解释,设备的人生值得我们去分析。

我相信科学不相信迷信,港剧里俺最喜欢的罗嘉良在迷离档案里说,要用科学来研究迷信。咱们现在就沿着设备的生命线走一走,看看其中都发生了什么。

首先当然是你将usb设备连接在hub的某个端口上,hub检测到有设备连接了进来,它也知道有朋自远方来不亦乐乎,于是精神头儿就上来了,就觉得有必要为设备做点什么。它会为设备分配一个struct usb_device结构的对象并初始化,并调用设备模型提供的接口将设备添加到usb总线的设备列表里,然后usb总线会遍历驱动列表里的每个驱动,调用自己的match函数看它们和你的设备或接口是否匹配。这不,又走到match函数了,那接下来那,先看看前面的,等真正遇到它的时候再说。

这么说是不是很不过瘾?本来满怀期待的耗费一个匹萨的钱去上海影城看大片儿,结果只看到了一个小馒头和一个圆环套圆环娱乐城。为了看清楚那一个馒头背后的故事,接下来只要你不嫌烦,咱就往细里去说,说到你烦为止。

hub检测到自己的某个端口有设备连接了进来后,它会调用core里的usb_alloc_dev函数为struct usb_device结构的对象申请内存,这个函数在drivers/usb/core/usb.c文件里定义

226 /**

227  * usb_alloc_dev - usb device constructor (usbcore-internal)

228  * @parent: hub to which device is connected; null to allocate a root hub

229  * @bus: bus used to access the device

230  * @port1: one-based index of port; ignored for root hubs

231  * Context: !in_interrupt()

232  *

233  * Only hub drivers (including virtual root hub drivers for host

234  * controllers) should ever call this.

235  *

236  * This call may not be used in a non-sleeping context.

237  */

238 struct usb_device *

239 usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)

240 {

241         struct usb_device *dev;

243         dev = kzalloc(sizeof(*dev), GFP_KERNEL);

244         if (!dev)

245                 return NULL;

247         if (!usb_get_hcd(bus_to_hcd(bus))) {

248                 kfree(dev);

249                 return NULL;

250         }

252         device_initialize(&dev->dev);

253         dev->dev.bus = &usb_bus_type;

254         dev->dev.type = &usb_device_type;

255         dev->dev.dma_mask = bus->controller->dma_mask;

256         dev->state = USB_STATE_ATTACHED;

258         INIT_LIST_HEAD(&dev->ep0.urb_list);

259         dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;

260         dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;

261         /* ep0 maxpacket comes later, from device descriptor */

262         dev->ep_in[0] = dev->ep_out[0] = &dev->ep0;

264         /* Save readable and stable topology id, distinguishing devices

265          * by location for diagnostics, tools, driver model, etc.  The

266          * string is a path along hub ports, from the root.  Each device's

267          * dev->devpath will be stable until USB is re-cabled, and hubs

268          * are often labeled with these port numbers.  The bus_id isn't

269          * as stable:  bus->busnum changes easily from modprobe order,

270          * cardbus or pci hotplugging, and so on.

271          */

272         if (unlikely(!parent)) {

273                 dev->devpath[0] = '';

275                 dev->dev.parent = bus->controller;

276                 sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum);

277         } else {

278                 /* match any labeling on the hubs; it's one-based */

279                 if (parent->devpath[0] == '')

280                         snprintf(dev->devpath, sizeof dev->devpath,

281                                 "%d", port1);

282                 else

283                         snprintf(dev->devpath, sizeof dev->devpath,

284                                 "%s.%d", parent->devpath, port1);

286                 dev->dev.parent = &parent->dev;

287                 sprintf(&dev->dev.bus_id[0], "%d-%s",

288                         bus->busnum, dev->devpath);

290                 /* hub driver sets up TT records */

291         }

293         dev->portnum = port1;

294         dev->bus = bus;

295         dev->parent = parent;

296         INIT_LIST_HEAD(&dev->filelist);

298 #ifdef  CONFIG_PM

299         mutex_init(&dev->pm_mutex);

300         INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work);

301         dev->autosuspend_delay = usb_autosuspend_delay * HZ;

302 #endif

303         return dev;

304 }

usb_alloc_dev函数就相当于usb设备的构造函数,参数里边儿,parent是设备连接的那个hubbus是设备连接的那条总线,port

抱歉!评论已关闭.