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

📄 hc_simple.c

📁 USB驱动实验 基于清华大学的TEB-44B0实验平台
💻 C
📖 第 1 页 / 共 3 页
字号:
 * 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);}#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;	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, struct urb * 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 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;}#if 0 /* unused now (hne) *//*************************************************************************** * 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;}#endif // if0/*************************************************************************** * 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)) {			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 + -