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

📄 patch-2.4.4-sl811hs

📁 This is cypress sl811 driver. I think it is very useful. Thankyou.
💻 4-SL811HS
📖 第 1 页 / 共 5 页
字号:
+ * URB. 
+ *
+ * Input: lurb: URB 
+ *
+ * Return: none  
+ **************************************************************************/
+
+#ifdef HC_URB_TIMEOUT
+static 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;
+    }
+      		
+    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 

⌨️ 快捷键说明

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