Chinaunix首页 | 论坛 | 博客
  • 博客访问: 270821
  • 博文数量: 130
  • 博客积分: 4012
  • 博客等级: 上校
  • 技术积分: 2030
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-10 10:40
文章分类

全部博文(130)

文章存档

2010年(130)

我的朋友

分类: LINUX

2010-01-10 23:48:59

由此接口进入OHCI模块

将请求传输块urb交给端口ep,由其负责将urb所要传输的数据发送/接收
----------------------------------------------------
static int ohci_urb_enqueue ( struct usb_hcd           *hcd,
                              struct usb_host_endpoint *ep,
                              struct urb               *urb,
                              int                      mem_flags)
{
    struct ohci_hcd *ohci = hcd_to_ohci (hcd);
    struct ed       *ed;
    urb_priv_t      *urb_priv;
    unsigned int    pipe = urb->pipe;
    int             i, size = 0;
    unsigned long   flags;
    int             retval = 0;

#ifdef OHCI_VERBOSE_DEBUG
    urb_print (urb, "SUB", usb_pipein (pipe));
#endif
    if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval)))
        return -ENOMEM;

根据端点的类型确定size(size决定该端点上挂载的td的数目,除实时端点上的td外,其它端点上的td能够装载4K的数据)
|-----------------------------------------------------------------|
|   switch (ed->type) {                                           |
|       case PIPE_CONTROL:                                        |
|           if (urb->transfer_buffer_length > 4096)               |
|               return -EMSGSIZE;                                 |
|           size = 2;                                             |
|       default:                                                  |
|           size += urb->transfer_buffer_length / 4096;           |
|           if ((urb->transfer_buffer_length % 4096) != 0)        |
|               size++;                                           |
|           if (size == 0)                                        |
|               size++;                                           |
|           else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0 |
|               && (urb->transfer_buffer_length                   |
|                   % usb_maxpacket (urb->dev, pipe,              |
|                       usb_pipeout (pipe))) == 0)                |
|               size++;                                           |
|           break;                                                |
|       case PIPE_ISOCHRONOUS:                                    |
|           size = urb->number_of_packets;                        |
|           break;                                                |
|   }                                                             |
|-----------------------------------------------------------------|

给urb_priv_t分配空间,并为其上所挂载的td指针数组分配空间
|--------------------------------------------------------------------------------------|
|   urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (struct td *), mem_flags); |
|--------------------------------------------------------------------------------------|

    if (!urb_priv)
        return -ENOMEM;

初始化urb_priv以及其上的td指针数组(urb_priv_t->td[i])
|----------------------------------------------------------------------------|
|   memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *)); |
|   INIT_LIST_HEAD (&urb_priv->pending);                                     |
|   urb_priv->length = size;                                                 |
|   urb_priv->ed = ed;                                                       |
|   for (i = 0; i < size; i++) {                                             |
|       urb_priv->td [i] = td_alloc (ohci, mem_flags);                       |
|       if (!urb_priv->td [i]) {                                             |
|           urb_priv->length = i;                                            |
|           urb_free_priv (ohci, urb_priv);                                  |
|           return -ENOMEM;                                                  |
|       }                                                                    |
|   }                                                                        |
|----------------------------------------------------------------------------|


    spin_lock_irqsave (&ohci->lock, flags);
    if (!HC_IS_RUNNING(hcd->state)) {
        retval = -ENODEV;
        goto fail;
    }
    spin_lock (&urb->lock);

初始化urb->hcpriv(将加工好的的hcpriv挂载到urb上); urb->start_frame(如果是实时传输,则需要指定开始处理该urb的帧号);
|-------------------------------------------------------|
|   if (urb->status != -EINPROGRESS) {                  |
|       spin_unlock (&urb->lock);                       |
|       urb->hcpriv = urb_priv;                         |
|       finish_urb (ohci, urb, NULL);                   |
|       retval = 0;                                     |
|       goto fail;                                      |
|   }                                                   |
|   if (ed->state == ED_IDLE) {                         |
|       retval = ed_schedule(ohci, ed);                -| 根据ed的类型将ed插入相应队列中
|       if (retval < 0)                                 |
|           goto fail0;                                 |
|       if (ed->type == PIPE_ISOCHRONOUS) {             |
|           u16 frame = ohci_frame_no(ohci);            |
|           frame += max_t (u16, 8, ed->interval);      |
|           frame &= ~(ed->interval - 1);               |
|           frame |= ed->branch;                        |
|           urb->start_frame = frame;                   |
|       }                                               |
|   } else if (ed->type == PIPE_ISOCHRONOUS)            |
|       urb->start_frame = ed->last_iso + ed->interval; |
|   urb->hcpriv = urb_priv;                             |
|-------------------------------------------------------|

将urb需要发送的数据安排到相应的ed下的td队列中
(urb->hcpriv->td[]是本次传输请求所需要的td,
urb->transfer_dma是本次传输请求所要传输的数据,
td_submit_urb()将这些数据安排到td[i]中,并将该td[i]插入urb->hcpriv->ed.td_list中)
|--------------------------------------|
|   td_submit_urb (ohci, urb);         |
|--------------------------------------|

fail0:
    spin_unlock (&urb->lock);
fail:
    if (retval)
        urb_free_priv (ohci, urb_priv);
    spin_unlock_irqrestore (&ohci->lock, flags);
    return retval;
}

阅读(749) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~