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

📄 patch-2.4.4-sl811hs

📁 基于Linux的USB芯片SL811主机驱动程序,由芯片厂家提供.
💻 4-SL811HS
📖 第 1 页 / 共 5 页
字号:
+#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;+    }+      		+    if (hci->td_array->len != 0)+    {+        DBGERR ("ERROR: schedule, hci->td_array->len = 0x%x, s/b: 0\n",+		hci->td_array->len);+    }+++    /* schedule the next available interrupt transfer or the next+     * stage of the interrupt transfer */++    if (hci->td_array->len == 0 && !list_empty(&hci->intr_list)) +    {+        units_left = sh_scan_urb_list (hci, &hci->intr_list);+    }++    /* schedule the next available control transfer or the next+     * stage of the control transfer */+    +    if (hci->td_array->len == 0 && !list_empty(&hci->ctrl_list)+        && units_left > 0)+    {	+	units_left = sh_scan_urb_list (hci, &hci->ctrl_list);+    }++    /* schedule the next available bulk transfer or the next+     * stage of the bulk transfer */+ +    if (hci->td_array->len == 0 && !list_empty(&hci->bulk_list)+        && units_left > 0)+    {+	sh_scan_urb_list (hci, &hci->bulk_list);++        /* be fair to each BULK URB (move list head around) +	 * only when the new SOF happens */+	+	lh = hci->bulk_list.next;+	list_del (&hci->bulk_list);+	list_add (&hci->bulk_list, lh);+    }+    return 0;+}++/***************************************************************************+ * Function Name : sh_add_packet+ *+ * This function forms the packet and transmit the packet. This function+ * will handle all endpoint type: isochoronus, interrupt, control, and + * bulk.+ * + * Input: hci = data structure for the host controller + *        urb = USB request block data structure + *+ * Return: 0 = unsucessful; 1 = successful   + **************************************************************************/++static int sh_add_packet (hci_t * hci, urb_t * 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;+	+    DBGFUNC ("enter sh_add_packet\n");+    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;

⌨️ 快捷键说明

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