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

📄 hc_simple.c

📁 基于linux嵌入式操作系统,sl811芯片的usb驱动源代码以及例子和Makefile.
💻 C
📖 第 1 页 / 共 3 页
字号:
 * 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) {    urb_t * urb = (urb_t *) lurb;    DBGFUNC ("enter qu_urb_timeout\n");    urb->transfer_flags |= USB_TIMEOUT_KILLED;    hci_unlink_urb (urb);}#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 (urb_t * 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 (urb_t * 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, urb_t * urb, epd_t * ed) {    int urb_state = 0;    DBGFUNC ("enter qu_queue_active_urb\n");    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, urb_t * urb){    struct hci_device * hci_dev = usb_to_hci (urb->dev);    epd_t * ed = &hci_dev->ed [qu_pipeindex (urb->pipe)];    DBGFUNC ("Enter qu_queue_urb\n");    /* for ISOC transfers calculate start frame index */            if (usb_pipeisoc (urb->pipe) && urb->transfer_flags & USB_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 urb_t * qu_next_urb (hci_t * hci, urb_t * 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, urb_t, 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 urb_t * qu_return_urb (hci_t * hci, urb_t * urb, int resub_ok) {    urb_t * 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;    urb_t * urb;    DBGFUNC ("enter sh_scan_iso_urb_list\n");    hci->td_array->len = 0;    while  (lh != list_lh)     {        urb = list_entry (lh, urb_t, 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;    urb_t * 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, urb_t, urb_list);	if (urb == NULL)	    return 1; 	if (!usb_pipeint (urb->pipe) ||(((hci->frame_number - urb->start_frame)             & 0x7ff) >= urb->interval))         {	    DBGVERBOSE("sh_scan_urb_list !INT: %d fr_no: %d int: %d pint: %d\n",                        urb->start_frame, hci->frame_number, urb->interval,                         usb_pipeint (urb->pipe));	    if (!sh_add_packet (hci, urb))            {	       	return 0;            }	    else             {	        DBGVERBOSE("INT: start: %d fr_no: %d int: %d pint: %d\n",                             urb->start_frame, hci->frame_number, urb->interval,                            usb_pipeint (urb->pipe));		urb->start_frame = hci->frame_number;		return 0;				    }	}    }    return 1;}/*************************************************************************** * Function Name : sh_shedule_trans * * This function schedule the USB transaction. * This function will process the endpoint in the following order:  * interrupt, control, and bulk.     *  * Input: hci = data structure for the host controller  *        isSOF = flag indicate if Start Of Frame has occurred  * * Return: 0    **************************************************************************/static int sh_schedule_trans (hci_t * hci, int isSOF){    int units_left = 1;    struct list_head * lh;    if (hci == NULL)    {       DBGERR ("sh_schedule_trans: hci == NULL\n");       return 0;    }    if (hci->td_array == NULL)    {       DBGERR ("sh_schedule_trans: hci->td_array == NULL\n");       return 0;    }

⌨️ 快捷键说明

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