Linux那些事儿之我是UHCI(17)Root Hub的控制传输(一)

虽然最伟大的probe函数就这样结束了.但是,我们的道路还很长,困难还很多,最终的结局是未知数,我们的故事和社会主义的航班一样,还不知要驶向何处.

在剩下的篇幅中,除了最后的电源管理部分以外,我们将围绕一个函数进行展开,这个函数就是usb_submit_urb().子曾经曰过:不吃饭的女人这世上也许还有好几个,不吃醋的女人却连一个也没有.我也曾经曰过:不遵循usb specUSB设备这世上也许还有好几个,不调用usb_submit_urb()USB设备驱动却连一个也没有.想必一路走来的兄弟们早就想知道神秘的usb_submit_urb()函数究竟是怎么混的吧?

不管是控制传输,还是中断传输,或是Bulk传输,又或者等时传输,设备驱动都一定会调用usb_submit_urb函数,只有通过它才能提交urb.所以接下来我们就分类来看这个函数,看看四种传输分别是如何处理的.

不过我们仍然先假设还没有设备插入Root Hub.因为Root Hub始终是一个特殊的角色,它的特殊地位决定了我们必须特殊对待.Hub只涉及到两种传输方式,即控制传输和中断传输.我们先来看控制传输,确切的说是先看Root Hub的控制传输.

还记得刚才在register_root_hub中那个usb_get_device_descriptor?我们在hub driver中讲过,也贴过代码,它会调用usb_get_descriptor,而后者会调用usb_control_msg,usb_control_msg则调用usb_internal_control_msg,然后usb_start_wait_urb会被调用,但最终会被调用的是usb_submit_urb().于是我们就来看一下usb_submit_urb()究竟何德何能让大家如此景仰,我们来看这个设备描述符究竟是如何获得的.

这个函数显然分量比较重,它来自drivers/usb/core/urb.c:

    107 /**

    108  * usb_submit_urb - issue an asynchronous transfer request for an endpoint

    109  * @urb: pointer to the urb describing the request

    110  * @mem_flags: the type of memory to allocate, see kmalloc() for a list

    111  *      of valid options for this.

    112  *

    113  * This submits a transfer request, and transfers control of the URB

    114  * describing that request to the USB subsystem.  Request completion will

    115  * be indicated later, asynchronously, by calling the completion handler.

    116  * The three types of completion are success, error, and unlink

    117  * (a software-induced fault, also called "request cancellation").

    118  *

    119  * URBs may be submitted in interrupt context.

    120  *

    121  * The caller must have correctly initialized the URB before submitting

    122  * it.  Functions such as usb_fill_bulk_urb() and usb_fill_control_urb() are

    123  * available to ensure that most fields are correctly initialized, for

    124  * the particular kind of transfer, although they will not initialize

    125  * any transfer flags.

    126  *

    127  * Successful submissions return 0; otherwise this routine returns a

    128  * negative error number.  If the submission is successful, the complete()

    129  * callback from the URB will be called exactly once, when the USB core and

    130  * Host Controller Driver (HCD) are finished with the URB.  When the completion

    131  * function is called, control of the URB is returned to the device

    132  * driver which issued the request.  The completion handler may then

    133  * immediately free or reuse that URB.

    134  *

    135  * With few exceptions, USB device drivers should never access URB fields

    136  * provided by usbcore or the HCD until its complete() is called.

    137  * The exceptions relate to periodic transfer scheduling.  For both

    138  * interrupt and isochronous urbs, as part of successful URB submission

    139  * urb->interval is modified to reflect the actual transfer period used

    140  * (normally some power of two units).  And for isochronous urbs,

    141  * urb->start_frame is modified to reflect when the URB's transfers were

    142  * scheduled to start.  Not all isochronous transfer scheduling policies

    143  * will work, but most host controller drivers should easily handle ISO

    144  * queues going from now until 10-200 msec into the future.

    145  *

146  * For control endpoints, the synchronous usb_control_msg() call is

    147  * often used (in non-interrupt context) instead of this call.

    148  * That is often used through convenience wrappers, for the requests

    149  * that are standardized in the USB 2.0 specification.  For bulk

    150  * endpoints, a synchronous usb_bulk_msg() call is available.

    151  *

    152  * Request Queuing:

    153  *

    154  * URBs may be submitted to endpoints before previous ones complete, to

    155  * minimize the impact of interrupt latencies and system overhead on data

    156  * throughput.  With that queuing policy, an endpoint's queue would never

    157  * be empty.  This is required for continuous isochronous data streams,

    158  * and may also be required for some kinds of interrupt transfers. Such

    159  * queuing also maximizes bandwidth utilization by letting USB controllers

    160  * start work on later requests before driver software has finished the

    161  * completion processing for earlier (successful) requests.

    162  *

    163  * As of Linux 2.6, all USB endpoint transfer queues support depths greater

    164  * than one.  This was previously a HCD-specific behavior, except for ISO

    165  * transfers.  Non-isochronous endpoint queues are inactive during cleanup

    166  * after faults (transfer errors or cancellation).

    167  *

    168  * Reserved Bandwidth Transfers:

    169  *

    170  * Periodic transfers (interrupt or isochronous) are performed repeatedly,

    171  * using the interval specified in the urb.  Submitting the first urb to

    172  * the endpoint reserves the bandwidth necessary to make those transfers.

    173  * If the USB subsystem can't allocate sufficient bandwidth to perform

    174  * the periodic request, submitting such a periodic request should fail.

    175  *

    176  * Device drivers must explicitly request that repetition, by ensuring that

    177  * some URB is always on the endpoint's queue (except possibly for short

    178  * periods during completion callacks).  When there is no longer an urb

    179  * queued, the endpoint's bandwidth reservation is canceled.  This means

    180  * drivers can use their completion handlers to ensure they keep bandwidth

    181  * they need, by reinitializing and resubmitting the just-completed urb

    182  * until the driver longer needs that periodic bandwidth.

    183  *

    184  * Memory Flags:

    185  *

    186  * The general rules for how to decide which mem_flags to use

    187  * are the same as for kmalloc.  There are four

    188  * different possible values; GFP_KERNEL, GFP_NOFS, GFP_NOIO and

189  * GFP_ATOMIC.

    190  *

    191  * GFP_NOFS is not ever used, as it has not been implemented yet.

    192  *

    193  * GFP_ATOMIC is used when

    194  *   (a) you are inside a completion handler, an interrupt, bottom half,

    195  *       tasklet or timer, or

    196  *   (b) you are holding a spinlock or rwlock (does not apply to

    197  *       semaphores), or

    198  *   (c) current->state != TASK_RUNNING, this is the case only after

    199  *       you've changed it.

    200  *

    201  * GFP_NOIO is used in the block io path and error handling of storage

    202  * devices.

    203  *

    204  * All other situations use GFP_KERNEL.

    205  *

    206  * Some more specific rules for mem_flags can be inferred, such as

    207  *  (1) start_xmit, timeout, and receive methods of network drivers must

    208  *      use GFP_ATOMIC (they are called with a spinlock held);

    209  *  (2) queuecommand methods of scsi drivers must use GFP_ATOMIC (also

    210  *      called with a spinlock held);

    211  *  (3) If you use a kernel thread with a network driver you must use

    212  *      GFP_NOIO, unless (b) or (c) apply;

    213  *  (4) after you have done a down() you can use GFP_KERNEL, unless (b) or (c)

    214  *      apply or your are in a storage driver's block io path;

    215  *  (5) USB probe and disconnect can use GFP_KERNEL unless (b) or (c) apply; and

    216  *  (6) changing firmware on a running storage or net device uses

    217  *      GFP_NOIO, unless b) or c) apply

    218  *

    219  */

    220 int usb_submit_urb(struct urb *urb, gfp_t mem_flags)

    221 {

    222         int                     pipe, temp, max;

    223         struct usb_device       *dev;

    224         int                     is_out;

    225

    226         if (!urb || urb->hcpriv || !urb->complete)

    227                 return -EINVAL;

    228         if (!(dev = urb->dev) ||

    229             (dev->state < USB_STATE_DEFAULT) ||

    230             (!dev->bus) || (dev->devnum <= 0))

    231                 return -ENODEV;

232         if (dev->bus->controller->power.power_state.event != PM_EVENT_ON

    233                         || dev->state == USB_STATE_SUSPENDED)

    234                 return -EHOSTUNREACH;

    235

    236         urb->status = -EINPROGRESS;

    237         urb->actual_length = 0;

    238

    239         /* Lots of sanity checks, so HCDs can rely on clean data

    240          * and don't need to duplicate tests

    241          */

    242         pipe = urb->pipe;

    243         temp = usb_pipetype(pipe);

    244         is_out = usb_pipeout(pipe);

    245

    246         if (!usb_pipecontrol(pipe) && dev->state < USB_STATE_CONFIGURED)

    247                 return -ENODEV;

    248

    249         /* FIXME there should be a sharable lock protecting us against

    250          * config/altsetting changes and disconnects, kicking in here.

    251          * (here == before maxpacket, and eventually endpoint type,

    252          * checks get made.)

    253          */

    254

    255         max = usb_maxpacket(dev, pipe, is_out);

    256         if (max <= 0) {

    257                 dev_dbg(&dev->dev,

    258                         "bogus endpoint ep%d%s in %s (bad maxpacket %d)/n",

    259                         usb_pipeendpoint(pipe), is_out ? "out" : "in",

    260                         __FUNCTION__, max);

    261                 return -EMSGSIZE;

    262         }

    263

    264         /* periodic transfers limit size per frame/uframe,

    265          * but drivers only control those sizes for ISO.

    266          * while we're checking, initialize return status.

    267          */

    268         if (temp == PIPE_ISOCHRONOUS) {

    269                 int     n, len;

    270

    271                 /* "high bandwidth" mode, 1-3 packets/uframe? */

    272                 if (dev->speed == USB_SPEED_HIGH) {

    273                         int     mult = 1 + ((max >> 11) & 0x03);

274                         max &= 0x07ff;

    275                         max *= mult;

    276                 }

    277

    278                 if (urb->number_of_packets <= 0)

    279                         return -EINVAL;

    280                 for (n = 0; n < urb->number_of_packets; n++) {

    281                         len = urb->iso_frame_desc[n].length;

    282                         if (len < 0 || len > max)

    283                                 return -EMSGSIZE;

    284                         urb->iso_frame_desc[n].status = -EXDEV;

    285                         urb->iso_frame_desc[n].actual_length = 0;

    286                 }

    287         }

    288

    289         /* the I/O buffer must be mapped/unmapped, except when length=0 */

    290         if (urb->transfer_buffer_length < 0)

    291                 return -EMSGSIZE;

    292

    293 #ifdef DEBUG

    294         /* stuff that drivers shouldn't do, but which shouldn't

    295          * cause problems in HCDs if they get it wrong.

    296          */

    297         {

    298         unsigned int    orig_flags = urb->transfer_flags;

    299         unsigned int    allowed;

    300

    301         /* enforce simple/standard policy */

    302         allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |

    303                         URB_NO_INTERRUPT);

    304         switch (temp) {

    305         case PIPE_BULK:

    306                 if (is_out)

    307                         allowed |= URB_ZERO_PACKET;

    308                 /* FALLTHROUGH */

    309         case PIPE_CONTROL:

310                 allowed |= URB_NO_FSBR; /* only affects UHCI */

    311                 /* FALLTHROUGH */

    312         default:                        /* all non-iso endpoints */

    313                 if (!is_out)

    314                         allowed |= URB_SHORT_NOT_OK;

    315                 break;

    316         case PIPE_ISOCHRONOUS:

    317                 allowed |= URB_ISO_ASAP;

    318                 break;

    319         }

    320         urb->transfer_flags &= allowed;

    321

    322         /* fail if submitter gave bogus flags */

    323         if (urb->transfer_flags != orig_flags) {

    324                 err("BOGUS urb flags, %x --> %x",

    325                         orig_flags, urb->transfer_flags);

    326                 return -EINVAL;

    327         }

    328         }

    329 #endif

    330         /*

    331          * Force periodic transfer intervals to be legal values that are

    332          * a power of two (so HCDs don't need to).

    333          *

    334          * FIXME want bus->{intr,iso}_sched_horizon values here.  Each HC

    335          * supports different values... this uses EHCI/UHCI defaults (and

    336          * EHCI can use smaller non-default values).

    337          */

    338         switch (temp) {

    339         case PIPE_ISOCHRONOUS:

    340         case PIPE_INTERRUPT:

    341                 /* too small? */

    342                 if (urb->interval <= 0)

    343                         return -EINVAL;

    344                 /* too big? */

    345                 switch (dev->speed) {

    346                 case USB_SPEED_HIGH:    /* units are microframes */

    347                         // NOTE usb handles 2^15

    348                         if (urb->interval > (1024 * 8))

    349                                 urb->interval = 1024 * 8;

    350                         temp = 1024 * 8;

    351                         break;

352                 case USB_SPEED_FULL:    /* units are frames/msec */

    353                 case USB_SPEED_LOW:

    354                         if (temp == PIPE_INTERRUPT) {

    355                                 if (urb->interval > 255)

    356                                         return -EINVAL;

    357                                 // NOTE ohci only handles up to 32

    358                                 temp = 128;

    359                         } else {

    360                                 if (urb->interval > 1024)

    361                                         urb->interval = 1024;

    362                                 // NOTE usb and ohci handle up to 2^15

    363                                 temp = 1024;

    364                         }

    365                         break;

    366                 default:

    367                         return -EINVAL;

    368                 }

    369                 /* power of two? */

    370                 while (temp > urb->interval)

    371                         temp >>= 1;

    372                 urb->interval = temp;

    373         }

    374

    375         return usb_hcd_submit_urb(urb, mem_flags);

    376 }

天哪,这个函数绝对够让你我看的七窍流血的.这种变态已经不能用语言来形容了,鲁迅先生看了一定会说我已经出离愤怒了!南唐的李煜在看完这段代码之后感慨道:问君能有几多愁,恰似太监上青楼!

这个函数的核心变量就是那个temp.很明显,它表示的就是传输管道的类型.我们说了现在考虑的是Root Hub的控制传输.那么很明显的事实是,usb_hcd_submit_urb会被调用,268行这个if语段和338行这个switch都没有什么意义.所以我们来看usb_hcd_submit_urb.

来自drivers/usb/core/hcd.c:

    916 /* may be called in any context with a valid urb->dev usecount

    917  * caller surrenders "ownership" of urb

    918  * expects usb_submit_urb() to have sanity checked and conditioned all

    919  * inputs in the urb

    920  */

    921 int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)

    922 {

    923         int                     status;

    924         struct usb_hcd          *hcd = bus_to_hcd(urb->dev->bus);

    925         struct usb_host_endpoint *ep;

    926         unsigned long           flags;

    927

    928         if (!hcd)

    929                 return -ENODEV;

    930

    931         usbmon_urb_submit(&hcd->self, urb);

    932

    933         /*

    934          * Atomically queue the urb,  first to our records, then to the HCD.

    935          * Access to urb->status is controlled by urb->lock ... changes on

    936          * i/o completion (normal or fault) or unlinking.

    937          */

    938

    939         // FIXME:  verify that quiescing hc works right (RH cleans up)

    940

    941         spin_lock_irqsave (&hcd_data_lock, flags);

    942         ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out)

    943                         [usb_pipeendpoint(urb->pipe)];

    944         if (unlikely (!ep))

    945                 status = -ENOENT;

    946         else if (unlikely (urb->reject))

    947                 status = -EPERM;

    948         else switch (hcd->state) {

    949         case HC_STATE_RUNNING:

    950         case HC_STATE_RESUMING:

    951 doit:

    952                 list_add_tail (&urb->urb_list, &ep->urb_list);

    953                 status = 0;

    954                 break;

955         case HC_STATE_SUSPENDED:

    956                 /* HC upstream links (register access, wakeup signaling) can work

    957                  * even when the downstream links (and DMA etc) are quiesced; let

    958                  * usbcore talk to the root hub.

    959                  */

    960                 if (hcd->self.controller->power.power_state.event == PM_EVENT_ON

    961                                 && urb->dev->parent == NULL)

    962                         goto doit;

    963                 /* FALL THROUGH */

    964         default:

    965                 status = -ESHUTDOWN;

    966                 break;

    967         }

    968         spin_unlock_irqrestore (&hcd_data_lock, flags);

    969         if (status) {

    970                 INIT_LIST_HEAD (&urb->urb_list);

    971                 usbmon_urb_submit_error(&hcd->self, urb, status);

    972                 return status;

    973         }

    974

    975         /* increment urb's reference count as part of giving it to the HCD

    976          * (which now controls it).  HCD guarantees that it either returns

    977          * an error or calls giveback(), but not both.

    978          */

    979         urb = usb_get_urb (urb);

    980         atomic_inc (&urb->use_count);

    981

    982         if (urb->dev == hcd->self.root_hub) {

    983                 /* NOTE:  requirement on hub callers (usbfs and the hub

    984                  * driver, for now) that URBs' urb->transfer_buffer be

    985                  * valid and usb_buffer_{sync,unmap}() not be needed, since

    986                  * they could clobber root hub response data.

    987                  */

    988                 status = rh_urb_enqueue (hcd, urb);

    989                 goto done;

    990         }

    991

    992         /* lower level hcd code should use *_dma exclusively,

    993          * unless it uses pio or talks to another transport.

    994          */

    995         if (hcd->self.uses_dma) {

    996                 if (usb_pipecontrol (urb->pipe)

997                         && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))

    998                         urb->setup_dma = dma_map_single (

    999                                         hcd->self.controller,

   1000                                         urb->setup_packet,

   1001                                         sizeof (struct usb_ctrlrequest),

   1002                                         DMA_TO_DEVICE);

   1003                 if (urb->transfer_buffer_length != 0

   1004                         && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))

   1005                         urb->transfer_dma = dma_map_single (

   1006                                         hcd->self.controller,

   1007                                         urb->transfer_buffer,

   1008                                         urb->transfer_buffer_length,

   1009                                         usb_pipein (urb->pipe)

   1010                                             ? DMA_FROM_DEVICE

   1011                                             : DMA_TO_DEVICE);

   1012         }

   1013

   1014         status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags);

   1015 done:

   1016         if (unlikely (status)) {

   1017                 urb_unlink (urb);

   1018                 atomic_dec (&urb->use_count);

   1019                 if (urb->reject)

   1020                         wake_up (&usb_kill_urb_queue);

   1021                 usbmon_urb_submit_error(&hcd->self, urb, status);

   1022                 usb_put_urb (urb);

   1023         }

   1024         return status;

   1025 }

凡是名字中带着usbmon的函数咱们都甭管,它是一个usb的监控工具,启用不启用这个工具取决于一个编译选项,CONFIG_USB_MON,咱们假设不打开它,这样它的这些函数实际上就都是些空函数.就比如931行的usbmon_urb_submit,以及下面的这个usbmon_urb_submit_error.

942这一行,得到与这个urb相关的struct usb_host_endpoint结构体指针ep,事实上struct urbstruct usb_host_endpoint这两个结构体中都有一个成员struct list_head urb_list,所以我们有952这么一行,每个endpoint都维护着一个队列,所有与它相关的urb都被放入到这个队列中,952行所做的就是这件事.当然,之所以我们现在会执行952,是因为我们的hcd->statestart_rh中被设置成了HC_STATE_RUNNING.

接着,以一种一目十行的手法我们发现,对于Root Hub, rh_urb_enqueue会被执行,对于非Root Hub,即一般的Hub,driver->urb_enqueue会被执行,对于uhci来说,就是uhci_urb_enqueue会被执行.我们先来看Root Hub.

rh_urb_enqueue来自drivers/usb/core/hcd.c:

    629 static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb)

    630 {

    631         if (usb_pipeint (urb->pipe))

    632                 return rh_queue_status (hcd, urb);

    633         if (usb_pipecontrol (urb->pipe))

    634                 return rh_call_control (hcd, urb);

    635         return -EINVAL;

636 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值