⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hc_simple.c

📁 isp1161a USB主控制芯片驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
        dma_addr_t              *dma){        hci_t	*hci = bus->hcpriv;        /* some USB hosts just use PIO */        if (!bus->controller->dma_mask) {                *dma = ~(dma_addr_t) 0;                return kmalloc (size, mem_flags);        }        return dma_alloc_coherent (hci->bus->controller, size, dma, 0);}static void hci_buffer_free (        struct usb_bus          *bus,        size_t                  size,        void                    *addr,        dma_addr_t              dma){        hci_t   *hci = bus->hcpriv;        if (!addr)                return;        if (!bus->controller->dma_mask) {                kfree (addr);                return;        }        dma_free_coherent (hci->bus->controller, size, addr, dma);}/*************************************************************************** * List of all io-functions  **************************************************************************/static struct usb_operations hci_device_operations = {    allocate:        hci_alloc_dev,    deallocate:        hci_free_dev,    get_frame_number:    hci_get_current_frame_number,    submit_urb:        hci_submit_urb,    unlink_urb:        hci_unlink_urb,    buffer_alloc:         hci_buffer_alloc,    buffer_free:         hci_buffer_free,};/*************************************************************************** * URB queueing: *  * For each type of transfer (INTR, BULK, ISO, CTRL) there is a list of  * active URBs. * (hci->intr_list, hci->bulk_list, hci->iso_list, hci->ctrl_list) * For every endpoint the head URB of the queued URBs is linked to one of  * those lists. *  * The rest of the queued URBs of an endpoint are linked into a  * private URB list for each endpoint. (hci_dev->ed [endpoint_io].urb_queue) * hci_dev->ed [endpoint_io].pipe_head .. points to the head URB which is  * in one of the active URB lists. *  * The index of an endpoint consists of its number and its direction. *  * The state of an intr and iso URB is 0.  * For ctrl URBs the states are US_CTRL_SETUP, US_CTRL_DATA, US_CTRL_ACK * Bulk URBs states are US_BULK and US_BULK0 (with 0-len packet) *  **************************************************************************//*************************************************************************** * Function Name : qu_urb_timeout * * This function is called when the URB timeout. The function unlinks the  * URB.  * * Input: lurb: URB  * * Return: none   **************************************************************************/#ifdef HC_URB_TIMEOUTstatic void qu_urb_timeout (unsigned long lurb){    struct urb *urb = (struct urb *) lurb;    DBGFUNC ("enter qu_urb_timeout\n");    urb->transfer_flags |= USB_TIMEOUT_KILLED;    hci_unlink_urb (urb, 0);}#endif/*************************************************************************** * Function Name : qu_pipeindex * * This function gets the index of the pipe.    * * Input: pipe: the urb pipe  * * Return: index   **************************************************************************/static inline int qu_pipeindex (__u32 pipe){    DBGFUNC ("enter qu_pipeindex\n");    return (usb_pipeendpoint (pipe) << 1) | (usb_pipecontrol (pipe) ? 0 : usb_pipeout (pipe));}/*************************************************************************** * Function Name : qu_seturbstate * * This function set the state of the URB.   *  * control pipe: 3 states -- Setup, data, status * interrupt and bulk pipe: 1 state -- data     * * Input: urb = USB request block data structure  *        state = the urb state * * Return: none   **************************************************************************/static inline void qu_seturbstate (struct urb * urb, int state){    DBGFUNC ("enter qu_seturbstate/\n");    urb->pipe &= ~0x1f;    urb->pipe |= (state & 0x1f);}/*************************************************************************** * Function Name : qu_urbstate * * This function get the current state of the URB.   *  * Input: urb = USB request block data structure  * * Return: none   **************************************************************************/static inline int qu_urbstate (struct urb * urb){    DBGFUNC ("enter qu_urbstate\n");    return urb->pipe & 0x1f;}/*************************************************************************** * Function Name : qu_queue_active_urb * * This function adds the urb to the appropriate active urb list and set * the urb state. *  * There are four active lists: isochoronous list, interrupt list,  * control list, and bulk list. *  * Input: hci = data structure for the host controller  *        urb = USB request block data structure  *        ed = endpoint descriptor * * Return: none   **************************************************************************/static inline void qu_queue_active_urb (hci_t * hci, struct urb * urb, epd_t * ed){    int urb_state = 0;    switch (usb_pipetype (urb->pipe)) {        case PIPE_CONTROL:        list_add (&urb->urb_list, &hci->ctrl_list);        urb_state = US_CTRL_SETUP;        break;        case PIPE_BULK:        list_add (&urb->urb_list, &hci->bulk_list);        if ((urb->transfer_flags & USB_ZERO_PACKET)            && urb->transfer_buffer_length > 0            &&            ((urb->transfer_buffer_length %                usb_maxpacket (urb->dev, urb->pipe,                    usb_pipeout (urb->pipe))) == 0)) {            urb_state = US_BULK0;        }        break;        case PIPE_INTERRUPT:        urb->start_frame = hci->frame_number;        list_add (&urb->urb_list, &hci->intr_list);        break;        case PIPE_ISOCHRONOUS:        list_add (&urb->urb_list, &hci->iso_list);        break;    }#ifdef HC_URB_TIMEOUT    if (urb->timeout) {        ed->timeout.data = (unsigned long) urb;        ed->timeout.expires = urb->timeout + jiffies;        ed->timeout.function = qu_urb_timeout;        add_timer (&ed->timeout);    }#endif    qu_seturbstate (urb, urb_state);}/*************************************************************************** * Function Name : qu_queue_urb * * This function adds the urb to the endpoint descriptor list  *  * Input: hci = data structure for the host controller  *        urb = USB request block data structure  * * Return: none   **************************************************************************/static int qu_queue_urb (hci_t * hci, struct urb * urb){    struct hci_device *hci_dev = usb_to_hci (urb->dev);    epd_t *ed = &hci_dev->ed[qu_pipeindex (urb->pipe)];    /* for ISOC transfers calculate start frame index */    if (usb_pipeisoc (urb->pipe) && urb->transfer_flags & URB_ISO_ASAP) {        urb->start_frame = ((ed->pipe_head) ? (ed->last_iso + 1) : hci_get_current_frame_number (urb-> dev) + 1) & 0xffff;    }    if (ed->pipe_head) {        __list_add (&urb->urb_list, ed->urb_queue.prev,                &(ed->urb_queue));    } else {        ed->pipe_head = urb;        qu_queue_active_urb (hci, urb, ed);        if (++hci->active_urbs == 1)            hc_start_int (hci);    }    return 0;}/*************************************************************************** * Function Name : qu_next_urb * * This function removes the URB from the queue and add the next URB to  * active list.  *  * Input: hci = data structure for the host controller  *        urb = USB request block data structure  *        resub_ok = resubmit flag * * Return: pointer to the next urb   **************************************************************************/static struct urb *qu_next_urb (hci_t * hci, struct urb * urb, int resub_ok){    struct hci_device *hci_dev = usb_to_hci (urb->dev);    epd_t *ed = &hci_dev->ed[qu_pipeindex (urb->pipe)];    DBGFUNC ("enter qu_next_urb\n");    list_del (&urb->urb_list);    INIT_LIST_HEAD (&urb->urb_list);    if (ed->pipe_head == urb) {#ifdef HC_URB_TIMEOUT        if (urb->timeout)            del_timer (&ed->timeout);#endif        if (!--hci->active_urbs)            hc_stop_int (hci);        if (!list_empty (&ed->urb_queue)) {            urb = list_entry (ed->urb_queue.next, struct urb, urb_list);            list_del (&urb->urb_list);            INIT_LIST_HEAD (&urb->urb_list);            ed->pipe_head = urb;            qu_queue_active_urb (hci, urb, ed);        } else {            ed->pipe_head = NULL;            urb = NULL;        }    }    return urb;}/*************************************************************************** * Function Name : qu_return_urb * * This function is part of the return path.    *  * Input: hci = data structure for the host controller  *        urb = USB request block data structure  *        resub_ok = resubmit flag * * Return: pointer to the next urb   **************************************************************************/static struct urb *qu_return_urb (hci_t * hci, struct urb * urb, int resub_ok){    struct urb *next_urb;    DBGFUNC ("enter qu_return_rub\n");    next_urb = qu_next_urb (hci, urb, resub_ok);    hcs_return_urb (hci, urb, resub_ok);    return next_urb;}/*************************************************************************** * Function Name : sh_scan_iso_urb_list * * This function goes throught the isochronous urb list and schedule the  * the transfer.    * * Note: This function has not tested yet *  * Input: hci = data structure for the host controller  *        list_lh = pointer to the isochronous list  *        frame_number = the frame number  * * Return: 0 = unsuccessful; 1 = successful   **************************************************************************/static int sh_scan_iso_urb_list (hci_t * hci, struct list_head *list_lh,                 int frame_number){    struct list_head *lh = list_lh->next;    struct urb *urb;    DBGFUNC ("enter sh_scan_iso_urb_list\n");    hci->td_array->len = 0;    while (lh != list_lh) {        urb = list_entry (lh, struct urb, urb_list);        lh = lh->next;        if (((frame_number - urb->start_frame) & 0x7ff) <            urb->number_of_packets) {            if (!sh_add_packet (hci, urb)) {                return 0;            } else {                if (((frame_number -                      urb->start_frame) & 0x7ff) > 0x400) {                    if (qu_urbstate (urb) > 0) {                        urb = qu_return_urb (hci, urb, 1);                    } else {                        urb = qu_next_urb (hci, urb, 1);                    }                    if (lh == list_lh && urb)                        lh = &urb->urb_list;                }            }        }    }    return 1;}/*************************************************************************** * Function Name : sh_scan_urb_list * * This function goes through the urb list and schedule the  * the transaction.    *  * Input: hci = data structure for the host controller  *        list_lh = pointer to the isochronous list  * * Return: 0 = unsuccessful; 1 = successful   **************************************************************************/static int sh_scan_urb_list (hci_t * hci, struct list_head *list_lh){    struct list_head *lh = NULL;    struct urb *urb;    if (list_lh == NULL) {        DBGERR ("sh_scan_urb_list: error, list_lh == NULL\n");    }    DBGFUNC ("enter sh_scan_urb_list: frame# \n");    list_for_each (lh, list_lh) {        urb = list_entry (lh, struct urb, urb_list);        if (urb == NULL)            return 1;        if (!usb_pipeint (urb->pipe)            || (((hci->frame_number - urb->start_frame)             & 0x7ff) >= urb->interval)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -