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

📄 hc_simple_isp116x.c

📁 usb isp116x 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}#endif	qu_seturbstate (urb, urb_state);}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 & USB_ISO_ASAP) {                urb->start_frame = ((ed->pipe_head)? (ed->last_iso + 1):				hci_get_current_frame_number (urb->dev) + 3) & 0xffff;              if (!(ed->pipe_head)){                 ed->last_iso = urb->start_frame;              }        }	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;}/*-------------------------------------------------------------------------*//* return path (after transfer) * remove URB from queue and return it to the api layer * */static struct urb * remove_urb (hci_t * hci, struct urb * urb){       int i;	struct hci_device * hci_dev = usb_to_hci (urb->dev);       for (i = 0; i < 32; i++) {		INIT_LIST_HEAD (&(hci_dev->ed [i].urb_queue));		hci_dev->ed [i].pipe_head = NULL;	}}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)];	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;}static struct urb * qu_return_urb (hci_t * hci, struct urb * urb, int resub_ok){	struct urb * next_urb;       next_urb = qu_next_urb (hci, urb, resub_ok);	hcs_return_urb (hci, urb, resub_ok);	return next_urb;}/*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*//* SCHEDULE operations * * * * */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;	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;}static int sh_scan_urb_list (hci_t * hci, struct list_head * list_lh){	struct list_head * lh;	struct urb * urb;	list_for_each (lh, list_lh) {		urb = list_entry (lh, struct urb, urb_list);		if (!usb_pipeint (urb->pipe) ||			(((hci->frame_number - urb->start_frame) & 0x7ff) >= urb->interval)) {					if (!sh_add_packet (hci, urb))					return 0;				else {					urb->start_frame = hci->frame_number;				}		}	}	return 1;}/*-------------------------------------------------------------------------*//* scan lists of active URBs and construct a schedule for a frame * */static int sh_schedule_trans (hci_t * hci){	int units_left;	struct list_head * lh;	hci->td_array->len = 0;	units_left = sh_scan_urb_list (hci, &hci->intr_list);	if (units_left) {  /* add CTRL transfers */		units_left = sh_scan_urb_list (hci, &hci->ctrl_list);	}	if (units_left) {  /* add BULK transfers */		sh_scan_urb_list (hci, &hci->bulk_list);	}	/* be fair to each BULK URB (move list head around) */	if (!list_empty (&hci->bulk_list)) {		lh = hci->bulk_list.next;		list_del (&hci->bulk_list);		list_add (&hci->bulk_list, lh);	}	return 0;}/*-------------------------------------------------------------------------*//* add some parts of the active URB to the schedule * */static int sh_add_packet (hci_t * hci, struct urb * urb){	__u8 * data = NULL;	int len = 0;	int toggle = 0;	int maxps = usb_maxpacket (urb->dev, urb->pipe, usb_pipeout (urb->pipe));	int endpoint = usb_pipeendpoint (urb->pipe);	int address = usb_pipedevice (urb->pipe);	int slow = usb_pipeslow (urb->pipe);	int out = usb_pipeout (urb->pipe);	int pid = 0;	int ret;	int i = 0;	int iso = 0;	if (maxps == 0) maxps = 8;	/* calculate len, toggle bit and add the transaction */	switch (usb_pipetype (urb->pipe)) {		case PIPE_ISOCHRONOUS:			pid = out ? PID_OUT : PID_IN;			iso = 1;			i = hci->frame_number - urb->start_frame;			hci->td_array = &hci->i_td_array [i & 1];			if (i == 1) hci->i_td_array[0].len = 1;			data = urb->transfer_buffer + urb->iso_frame_desc[i].offset;			len = urb->iso_frame_desc[i].length;			break;		case PIPE_BULK: /* BULK and BULK0 */		case PIPE_INTERRUPT:			pid = out ? PID_OUT : PID_IN;			len = urb->transfer_buffer_length - urb->actual_length;			data = urb->transfer_buffer + urb->actual_length;			toggle = usb_gettoggle (urb->dev, endpoint, out);			break;		case PIPE_CONTROL:			switch (qu_urbstate (urb)) {				case US_CTRL_SETUP:					len = 8;					pid = PID_SETUP;					data = urb->setup_packet;					toggle = 0;					break;				case US_CTRL_DATA:					if (urb->transfer_buffer_length != 0) {						pid = out ? PID_OUT : PID_IN;						len = urb->transfer_buffer_length - urb->actual_length;						data = urb->transfer_buffer + urb->actual_length;						toggle = (urb->actual_length & maxps) ? 0 : 1;						usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe),								usb_pipeout (urb->pipe), toggle);						break;					} else						/* correct state and fall through */						qu_seturbstate (urb, US_CTRL_ACK);				case US_CTRL_ACK:					len = 0;					/* reply in opposite direction */					pid = !out ? PID_OUT : PID_IN;					toggle = 1;					usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe),								usb_pipeout (urb->pipe), toggle);					break;			}	}	ret = hc_add_trans (hci, len, data, toggle, maxps, slow,						endpoint, address, pid, iso);#ifdef DEBUG1        printk("urb->start_frame =%d hci->frame_number=%d\n", urb->start_frame,hci->frame_number);        printk("transfer_pa: addr:%d ep:%d pid:%x tog:%x iso:%x sl:%x max:%d\n len:%d ret:%d data:%p left:%d\n",  			address, endpoint, pid, toggle, iso, slow, maxps, len, ret, data, hci->hp.units_left);#endif        if (ret >= 0) {		hci->td_array->td [hci->td_array->len].urb = urb;		hci->td_array->td [hci->td_array->len].len = ret;		hci->td_array->td [hci->td_array->len].iso_index = i;             hci->td_array->len = 1;		return 1;	}        return 0;}/*-------------------------------------------------------------------------*//* parse the done_list * */static int sh_done_list (hci_t * hci){	int actbytes;	int active = 0;	void * data = NULL;//	void * data_urb = NULL;	int cc;	int maxps;	int toggle;	struct urb * urb;	int urb_state;	int ret = 1; /* -1 parse abbort, 1 parse ok, 0 last element */	int trans = 0;	int len;	int iso_index = 0;       for (trans = 0; ret && trans < hci->td_array->len && trans < MAX_TRANS; trans++) {		urb = hci->td_array->td [trans].urb;		len = hci->td_array->td [trans].len;		if (usb_pipeisoc (urb->pipe)) {                    iso_index = hci->td_array->td [trans].iso_index;			data = urb->transfer_buffer +					urb->iso_frame_desc [iso_index].offset;			toggle = 0;		} else {			data = urb->transfer_buffer + urb->actual_length;			toggle = usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe),					usb_pipeout (urb->pipe));		}		urb_state = qu_urbstate (urb);		ret = hc_parse_trans (hci, &actbytes, data, &cc, &toggle, len);		maxps = usb_maxpacket (urb->dev, urb->pipe, usb_pipeout (urb->pipe));		if (maxps == 0) maxps = 8;#ifdef DEBUG1	printk("hc USB %d error %d in frame %d ep %d out %d addr %d actbytes %d:%p tog %d\n",						urb->error_count, cc, hci->frame_number,							usb_pipeendpoint (urb->pipe),							usb_pipeout (urb->pipe),							usb_pipedevice (urb->pipe),							actbytes, data, toggle);#endif		if (cc != TD_NOTACCESSED) {			active = (urb_state != US_CTRL_SETUP) &&					(actbytes && !(actbytes & (maxps - 1)) &&					(urb->transfer_buffer_length != urb->actual_length + actbytes));#ifdef DEBUG1	printk("hc USBx active %d, cc %x, urb_state %x, ret %x\n", active, cc, urb_state, ret);#endif			if (!(urb->transfer_flags & USB_DISABLE_SPD) && cc == TD_DATAUNDERRUN)								cc = 0;			if (cc) { /* last packet has an error */				if (hc_error_verbose)					printk("hc USB %d error %d in frame %d ep %d out %d addr %d au: %d\n",						urb->error_count, cc, hci->frame_number,							usb_pipeendpoint (urb->pipe),							usb_pipeout (urb->pipe), usb_pipedevice (urb->pipe), hci->active_urbs);				if (++urb->error_count > 3 || cc == TD_CC_STALL) {					active = 0;					urb_state = 0; /* return */				} else {					active = 1;				}			} else				urb->error_count = 0;			if (urb_state != US_CTRL_SETUP) { /* no error */				urb->actual_length += actbytes;				usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe),					usb_pipeout (urb->pipe),					toggle);			}			if (usb_pipeisoc (urb->pipe)) {				urb->iso_frame_desc [iso_index].actual_length = actbytes;				urb->iso_frame_desc [iso_index].status = cc_to_error [cc];				active = (iso_index < urb->number_of_packets - 1);			}			if (!active) {                                 if (!(urb_state--)) {                                 urb->status = cc_to_error [cc];					qu_return_urb (hci, urb, 1);				} else {					qu_seturbstate (urb, urb_state);				}			}		} else			urb->error_count = 0;	}	hci->td_array->len = 0;	return ret;}/*-------------------------------------------------------------------------*//* scan the delete list (qu_return_urb removes URB from list) * */static void sh_del_list (hci_t * hci){	struct list_head * lh = &hci->del_list;	struct urb * urb;	if (!list_empty (lh)) {		do {			lh = lh->next;			urb = list_entry (lh, struct urb, urb_list);			qu_return_urb (hci, urb, 0);		} while (!list_empty (lh));		wake_up (&hci->waitq);	}	return;}	

⌨️ 快捷键说明

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