Linux那些事儿之我是U盘(23)传说中的URB

来源:互联网 发布:javascript教程最新版 编辑:程序博客网 时间:2024/05/06 13:36

有人问,怎么写个驱动写这么久啊?有完没完啊?此水何时休?此恨何时已?

的确,一路走来,大家都不容易,但既然已经走到今天,我们能做的也只有是坚持下去.十年之前,我不认识你,你不属于我,但十年之后我依然记得那一年(1997),我的一个中学校友的那一句:不管前面是地雷阵还是万丈深渊,()都将一往无前,义无反顾,鞠躬尽瘁,死而后已.这个人叫朱镕基,毕业于长沙市一中.

usb_stor_acquire_resources,从名字上来看,获取资源.什么资源?网名为爬上墙头等红杏的朋友不禁表示出了一些好奇,之前不是申请了一大堆内存了吗?写个usb设备驱动程序怎么那么麻烦啊?不是专门为usb mass storage设备准备了一个struct us_data这么一个结构体了吗?不是说故事已经到高潮了吗?

周润发说得好,我还刚上路呢.没错,如果你以为看到这里你已经对usb设备驱动程序有了足够的认识,认为接下来的代码已经没有必要再分析了,那么,我只想说,上帝创造世界的计划中,未必包括使你会写usb设备驱动程序.

  的确,别看usb_stor_acquire_resources的代码不多,每一行都有每一行的故事.本节我们只讲其中的一行代码,没错,就是一行代码,因为我们需要隆重推出一个名词,一个响当当的名字,她就是传说中的urb,全称usb request block.usb设备需要通信,要传递数据,就需要使用urb,确切的说,应该是usb设备驱动程序使用urb.实际上,作为usb设备驱动,它本身并不能直接操纵数据的传输,usb这个大观园里,外接设备永远都是配角,真正的核心只是usb core,而真正负责调度的是usb host controller,这个您通常看不见的usb主机控制器芯片,他俨然是usb大观园中的大管家.设备驱动要发送信息,所需要做的是建立一个urb数据结构,并把这个数据结构交给核心层,而核心层会为所有设备统一完成调度,而设备在提交了urb之后需要做的,只是等待,等待,在那漫漫长夜中等待.别急,我们慢慢来.

760,一条赋值语句,等号左边,us->current_urb,等号右边,usb_alloc_urb函数被调用.如果说struct us_datausb mass storage中的主角,那么struct urb将毫无争议的成为整个usb子系统中的主角. Linux中所有的usb设备驱动,都必然也必须要使用urb.那么urb究竟长成什么样呢?她是如芙蓉姐姐那么婀娜多姿呢,又亦或是如林志玲那般无公害性感呢?include/linux/usb.h中能找到她的靓照:

614 /**
    615  * struct urb - USB Request Block
    616  * @urb_list: For use by current owner of the URB.
    617  * @pipe: Holds endpoint number, direction, type, and more.
    618  *      Create these values with the eight macros available;
    619  *      usb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is "ctrl"
    620  *      (control), "bulk", "int" (interrupt), or "iso" (isochronous).
    621  *      For example usb_sndbulkpipe() or usb_rcvintpipe().  Endpoint
    622  *      numbers range from zero to fifteen.  Note that "in" endpoint two
    623  *      is a different endpoint (and pipe) from "out" endpoint two.
    624  *      The current configuration controls the existence, type, and
    625  *      maximum packet size of any given endpoint.
    626  * @dev: Identifies the USB device to perform the request.
    627  * @status: This is read in non-iso completion functions to get the
    628  *      status of the particular request.  ISO requests only use it
    629  *      to tell whether the URB was unlinked; detailed status for
    630  *      each frame is in the fields of the iso_frame-desc.
    631  * @transfer_flags: A variety of flags may be used to affect how URB
    632  *      submission, unlinking, or operation are handled.  Different
    633  *      kinds of URB can use different flags.
    634  * @transfer_buffer:  This identifies the buffer to (or from) which
    635  *      the I/O request will be performed (unless URB_NO_TRANSFER_DMA_MAP
    636  *      is set).  This buffer must be suitable for DMA; allocate it with
    637  *      kmalloc() or equivalent.  For transfers to "in" endpoints, contents
    638  *      of this buffer will be modified.  This buffer is used for the data
    639  *      stage of control transfers.
    640  * @transfer_dma: When transfer_flags includes URB_NO_TRANSFER_DMA_MAP,
    641  *      the device driver is saying that it provided this DMA address,
    642  *      which the host controller driver should use in preference to the
    643  *      transfer_buffer.
    644  * @transfer_buffer_length: How big is transfer_buffer.  The transfer may
    645  *      be broken up into chunks according to the current maximum packet
    646  *      size for the endpoint, which is a function of the configuration
    647  *      and is encoded in the pipe.  When the length is zero, neither
    648  *      transfer_buffer nor transfer_dma is used.
    649  * @actual_length: This is read in non-iso completion functions, and
    650  *      it tells how many bytes (out of transfer_buffer_length) were
    651  *      transferred.  It will normally be the same as requested, unless
    652  *      either an error was reported or a short read was performed.
    653  *      The URB_SHORT_NOT_OK transfer flag may be used to make such
    654  *      short reads be reported as errors.
    655  * @setup_packet: Only used for control transfers, this points to eight bytes
    656  *      of setup data.  Control transfers always start by sending this data
    657  *      to the device.  Then transfer_buffer is read or written, if needed.
    658  * @setup_dma: For control transfers with URB_NO_SETUP_DMA_MAP set, the
    659  *      device driver has provided this DMA address for the setup packet.
    660  *      The host controller driver should use this in preference to
    661  *      setup_packet.
    662  * @start_frame: Returns the initial frame for isochronous transfers.
    663  * @number_of_packets: Lists the number of ISO transfer buffers.
    664  * @interval: Specifies the polling interval for interrupt or isochronous
    665  *      transfers.  The units are frames (milliseconds) for for full and low
    666  *      speed devices, and microframes (1/8 millisecond) for highspeed ones.
    667  * @error_count: Returns the number of ISO transfers that reported errors.
    668  * @context: For use in completion functions.  This normally points to
    669  *      request-specific driver context.
    670  * @complete: Completion handler. This URB is passed as the parameter to the
    671  *      completion function.  The completion function may then do what
    672  *      it likes with the URB, including resubmitting or freeing it.
    673  * @iso_frame_desc: Used to provide arrays of ISO transfer buffers and to
    674  *      collect the transfer status for each buffer.
    675  *
    676  * This structure identifies USB transfer requests.  URBs must be allocated by
    677  * calling usb_alloc_urb() and freed with a call to usb_free_urb().
    678  * Initialization may be done using various usb_fill_*_urb() functions.  URBs
    679  * are submitted using usb_submit_urb(), and pending requests may be canceled
    680  * using usb_unlink_urb() or usb_kill_urb().
    681  *
    682  * Data Transfer Buffers:
    683  *
    684  * Normally drivers provide I/O buffers allocated with kmalloc() or otherwise
    685  * taken from the general page pool.  That is provided by transfer_buffer
    686  * (control requests also use setup_packet), and host controller drivers
    687  * perform a dma mapping (and unmapping) for each buffer transferred.  Those
    688  * mapping operations can be expensive on some platforms (perhaps using a dma
    689  * bounce buffer or talking to an IOMMU),
    690  * although they're cheap on commodity x86 and ppc hardware.
    691  *
    692  * Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
    693  * which tell the host controller driver that no such mapping is needed since
    694  * the device driver is DMA-aware.  For example, a device driver might
    695  * allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
    696  * When these transfer flags are provided, host controller drivers will
    697  * attempt to use the dma addresses found in the transfer_dma and/or
    698  * setup_dma fields rather than determining a dma address themselves.  (Note
    699  * that transfer_buffer and setup_packet must still be set because not all
    700  * host controllers use DMA, nor do virtual root hubs).
    701  *
    702  * Initialization:
    703  *
    704  * All URBs submitted must initialize the dev, pipe, transfer_flags (may be
    705  * zero), and complete fields.
    706  * The URB_ASYNC_UNLINK transfer flag affects later invocations of
    707  * the usb_unlink_urb() routine.  Note: Failure to set URB_ASYNC_UNLINK
    708  * with usb_unlink_urb() is deprecated.  For synchronous unlinks use
    709  * usb_kill_urb() instead.
    710  *
    711  * All URBs must also initialize
    712  * transfer_buffer and transfer_buffer_length.  They may provide the
    713  * URB_SHORT_NOT_OK transfer flag, indicating that short reads are
    714  * to be treated as errors; that flag is invalid for write requests.
    715  *
    716  * Bulk URBs may
    717  * use the URB_ZERO_PACKET transfer flag, indicating that bulk OUT transfers
    718  * should always terminate with a short packet, even if it means adding an
    719  * extra zero length packet.
    720  *
    721  * Control URBs must provide a setup_packet.  The setup_packet and
    722  * transfer_buffer may each be mapped for DMA or not, independently of
    723  * the other.  The transfer_flags bits URB_NO_TRANSFER_DMA_MAP and
    724  * URB_NO_SETUP_DMA_MAP indicate which buffers have already been mapped.
    725  * URB_NO_SETUP_DMA_MAP is ignored for non-control URBs.
    726  *
    727  * Interrupt URBs must provide an interval, saying how often (in milliseconds
    728  * or, for highspeed devices, 125 microsecond units)
    729  * to poll for transfers.  After the URB has been submitted, the interval
    730  * field reflects how the transfer was actually scheduled.
    731  * The polling interval may be more frequent than requested.
    732  * For example, some controllers have a maximum interval of 32 microseconds,
    733  * while others support intervals of up to 1024 microseconds.
    734  * Isochronous URBs also have transfer intervals.  (Note that for isochronous
    735  * endpoints, as well as high speed interrupt endpoints, the encoding of
    736  * the transfer interval in the endpoint descriptor is logarithmic.
    737  * Device drivers must convert that value to linear units themselves.)
    738  *
    739  * Isochronous URBs normally use the URB_ISO_ASAP transfer flag, telling
    740  * the host controller to schedule the transfer as soon as bandwidth
    741  * utilization allows, and then set start_frame to reflect the actual frame
    742  * selected during submission.  Otherwise drivers must specify the start_frame
    743  * and handle the case where the transfer can't begin then.  However, drivers
    744  * won't know how bandwidth is currently allocated, and while they can
    745  * find the current frame using usb_get_current_frame_number () they can't
    746  * know the range for that frame number.  (Ranges for frame counter values
    747  * are HC-specific, and can go from 256 to 65536 frames from "now".)
    748  *
    749  * Isochronous URBs have a different data transfer model, in part because
    750  * the quality of service is only "best effort".  Callers provide specially
    751  * allocated URBs, with number_of_packets worth of iso_frame_desc structures
    752  * at the end.  Each such packet is an individual ISO transfer.  Isochronous
    753  * URBs are normally queued, submitted by drivers to arrange that
    754  * transfers are at least double buffered, and then explicitly resubmitted
    755  * in completion handlers, so
    756  * that data (such as audio or video) streams at as constant a rate as the
    757  * host controller scheduler can support.
    758  *
    759  * Completion Callbacks:
    760  *
    761  * The completion callback is made in_interrupt(), and one of the first
    762  * things that a completion handler should do is check the status field.
    763  * The status field is provided for all URBs.  It is used to report
    764  * unlinked URBs, and status for all non-ISO transfers.  It should not
    765  * be examined before the URB is returned to the completion handler.
    766  *
    767  * The context field is normally used to link URBs back to the relevant
    768  * driver or request state.
    769  *
    770  * When the completion callback is invoked for non-isochronous URBs, the
    771  * actual_length field tells how many bytes were transferred.  This field
    772  * is updated even when the URB terminated with an error or was unlinked.
    773  *
    774  * ISO transfer status is reported in the status and actual_length fields
    775  * of the iso_frame_desc array, and the number of errors is reported in
    776  * error_count.  Completion callbacks for ISO transfers will normally
    777  * (re)submit URBs to ensure a constant transfer rate.
    778  */
    779 struct urb
    780 {
    781         /* private, usb core and host controller only fields in the urb */
    782         struct kref kref;               /* reference count of the URB */
    783         spinlock_t lock;                /* lock for the URB */
    784         void *hcpriv;                   /* private data for host controller */
    785         struct list_head urb_list;      /* list pointer to all active urbs */
    786         int bandwidth;                  /* bandwidth for INT/ISO request */
    787         atomic_t use_count;             /* concurrent submissions counter */
    788         u8 reject;                      /* submissions will fail */
    789
    790         /* public, documented fields in the urb that can be used by drivers */
    791         struct usb_device *dev;         /* (in) pointer to associated device */
    792         unsigned int pipe;              /* (in) pipe information */
    793         int status;                     /* (return) non-ISO status */
    794         unsigned int transfer_flags;    /* (in) URB_SHORT_NOT_OK | ...*/
    795         void *transfer_buffer;          /* (in) associated data buffer */
    796         dma_addr_t transfer_dma;        /* (in) dma addr for transfer_buffer */
    797         int transfer_buffer_length;     /* (in) data buffer length */
    798         int actual_length;              /* (return) actual transfer length */
    799         unsigned char *setup_packet;    /* (in) setup packet (control only) */
    800         dma_addr_t setup_dma;           /* (in) dma addr for setup_packet */
    801         int start_frame;                /* (modify) start frame (ISO) */
    802         int number_of_packets;          /* (in) number of ISO packets */
    803         int interval;                   /* (modify) transfer interval (INT/ISO) */
    804         int error_count;                /* (return) number of ISO errors */
    805         void *context;                  /* (in) context for completion */
    806         usb_complete_t complete;        /* (in) completion routine */
    807         struct usb_iso_packet_descriptor iso_frame_desc[0];     /* (in) ISO ONLY */
    808 };

我们常常抱怨,Linux内核源代码中注释太少了,以至于我们常常看不懂那些代码究竟是什么含义.,urb让开发人员做足了文章,结构体struct urb的定义不过30,而说明文字却用了足足160余行.可见urb的江湖地位.有时候我真的怀疑这些写代码的人是不是以为自己的代码是按行计费的,这么一大串的注释他写得不累我们看得还累呢.当然我们这里贴出来主要还是为了保持原汁原味,另一方面这个注释也说得很清楚,对于每一个成员都解释了,而我们接下来将必然要用到urb的许多个成员.

此刻,我们暂时不去理会这个结构体每一个元素的作用,只需要知道,一个urb包含了执行usb传输所需要的所有信息.而作为驱动程序,要通信,就必须创建这么一个数据结构,并且为她赋好值,显然不同类型的传输,需要对urb赋不同的值,然后将她提交给底层,完了底层的usb core会找到相应的usb host controller,从而具体去实现数据的传输,传输完了之后,usb host controller会通知设备驱动程序.

总之我们知道,760行就是调用usb_alloc_urb()申请了一个struct urb结构体.关于usb_alloc_urb()这个函数,我们不打算讲,它是usb core所提供的一个函数,来自drivers/usb/core/urb.c,usb开发人员的确是给足了urb的面子,专门把和这个数据结构相关的代码整理在这么一个文件中了.我们可以在include/linux/usb.h中找到这个函数的声明,

    917 extern struct urb *usb_alloc_urb(int iso_packets, int mem_flags);

这个函数的作用很明显,就是为一个urb结构体申请内存,它有两个参数,其中第一个iso_packets用来在等时传输的方式下指定你需要传输多少个包,对于非等时模式来说,这个参数直接使用0.另一个参数mem_flags就是一个flag,表征申请内存的方式,这个flag将最终传递给kmalloc函数,我们这里传递的是GFP_KERNEL,这个flag是内存申请中最常用的,我们之前也用过,在为us申请内存的时候.usb_alloc_urb最终将返回一个urb指针,us的成员current_urb也是一个struct urb的指针,所以就赋给它了,不过需要记住,usb_alloc_urb除了申请内存以外,还对结构体作了初始化,结构体urb被初始化为0,虽然这里我们没有把这个函数的代码贴出来,但你也千万不要以为写代码的人跟你我似的,申请变量还能忘了初始化.同时,struct urb中还有一个引用计数,以及一个自旋锁,这些也同样被初始化了.

所以,接下来我们就将和us->current_urb打交道了.如果你对urb究竟怎么用还有些困惑的话,可以看看host controller的代码,如果你不想看,那么我可以用一种你最能接受的方式告诉你,usb是一种总线,是总线它就要通信,我们现实生活中真正要使用的是设备,但是光有设备还不足以实现usb通信,于是世界上有了usb host controller(usb主机控制器),它来负责统一调度,这就好比北京的交警,北京这个城市里真正需要的本来是车辆和行人,而光有车辆和行人,没有交警,那么这个城市里的车辆和行人必将乱套,于是诞生了交警这么一个行业,交警站在路口统一来管理调度那混乱的交通.假如车辆和行人可以完全自觉遵守某种规矩而来来往往于这个城市的每一个角落,每一个路口,那么交警就没有必要存在了.同样,假如设备能够完全自觉的传递信息,每一个数据包都能到达它应该去的地方,那么我们根本就不需要有主机控制器这么一个东西.然而,事实是,在北京,遵守交通规则的人不多,我相信每一个来过北京的人都会发现,在北京,闯红灯是一种时尚.我常常对自己说,如果哪一天我没有闯红灯,那么由此可以推导出来,这一天我一定没有出门.同样,usb的世界中,设备也总是那么的不守规矩,我们必须要设计一个东西出来管理来控制所有的usb设备的通信,这样,主机控制器就横空出世了.

那么设备和主机控制器的分工又是如何呢?硬件实现上我们就不说了,说点具体的,Linux,设备驱动程序只要为每一次请求准备一个urb结构体变量,把它填充好,(就是说赋上该赋的值)然后它调用usb core提供的函数,把这个urb传递给host controller,host controller就会把各个设备驱动程序所提交的urb统一规划,去执行每一个操作.而这期间,usb设备驱动程序通常会进入睡眠,而一旦host controllerurb要做的事情给做完了,它会调用一个函数去唤醒usb设备驱动程序,然后usb设备驱动程序就可以继续往下走了.这又好比我们学校里的师生关系.考试的时候,我们只管把试卷填好,然后我们交给老师,然后老师拿去批改试卷,这期间我们除了等待别无选择,等待老师改完了试卷,告诉了我们分数,我们又继续我们的生活.当然了,如果成绩不好,也许有些人的生活就不会继续了,在复旦,我们可以选择去曾经的绝情谷上吊,可以选择去第四教学楼顶层跳下来,在交大,则可以去跳思源湖.同样,usb设备驱动程序也是如此,如果urb提交给usb host,但是最终却没有成功执行,那么也许该usb设备驱动程序的生命也就提前结束.不过这都是后话,现在只要有个感性认识即可,稍后看到了就能更深刻的体会了,这种岗位分工的方式给我们编写设备驱动程序带来了巨大的方便.

 
原创粉丝点击