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

📄 patch-2.4.4-sl811hs

📁 This is cypress sl811 driver. I think it is very useful. Thankyou.
💻 4-SL811HS
📖 第 1 页 / 共 5 页
字号:
+ * 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;
+	    iso = 1;
+	    i = hci->frame_number - urb->start_frame;
+	    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 (!hci->last_packet_nak)
+		    {
+		        /* The last packet received is not a nak:
+		         * reset the nak count
+			 */
+
+			hci->nakCnt = 0;
+		    }
+		    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, qu_urbstate(urb));
+
+    DBGVERBOSE("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);
+	
+    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 ++;
+        hci->active_trans = 1;	
+	return 1;
+    }
+    return 0;
+}
+
+/***************************************************************************
+ * Function Name : cc_to_error
+ *
+ * This function maps the SL811HS hardware error code to the linux USB error
+ * code.
+ * 
+ * Input: cc = hardware error code 
+ *
+ * Return: USB error code   
+ **************************************************************************/
+
+static int cc_to_error (int cc)
+{
+    int errCode = 0;
+    if (cc & SL11H_STATMASK_ERROR)
+    {
+	errCode |= USB_ST_CRC;
+    }
+    else if (cc & SL11H_STATMASK_OVF)
+    {
+        errCode |= USB_ST_DATAOVERRUN;
+    }
+        else if (cc & SL11H_STATMASK_STALL)
+    {
+ 	errCode |= USB_ST_STALL;
+    }
+    return errCode;
+}
+
+/***************************************************************************
+ * Function Name : sh_done_list
+ *
+ * This function process the packet when it has done finish transfer.
+ * 
+ * 1) It handles hardware error
+ * 2) It updates the URB state
+ * 3) If the USB transaction is complete, it start the return stack path.
+ * 
+ * Input: hci = data structure for the host controller 
+ *        isExcessNak = flag tells if there excess NAK condition occurred 
+ *
+ * Return:  urb_state or -1 if the transaction has complete   
+ **************************************************************************/
+
+static int sh_done_list (hci_t * hci, int *isExcessNak) 
+{
+    int actbytes = 0;
+    int active = 0;
+    void * data = NULL; 
+    int cc;
+    int maxps;
+    int toggle;
+    urb_t * urb;
+    int urb_state=0;
+    int ret = 1; /* -1 parse abbort, 1 parse ok, 0 last element */
+    int trans = 0;
+    int len;
+    int iso_index = 0;
+    int out;
+    int pid = 0;
+    int debugLen = 0;
+
+    *isExcessNak =0;
+ 
+    DBGFUNC("enter sh_done_list: td_array->len = 0x%x\n", hci->td_array->len);
+
+    debugLen = hci->td_array->len;
+    if (debugLen > 1)
+	DBGERR ("sh_done_list: td_array->len = 0x%x > 1\n", hci->td_array->len);
+
+    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;
+	out = usb_pipeout(urb->pipe);	
+
+	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);
+	pid = out ? PID_OUT : PID_IN;
+	ret = hc_parse_trans (hci, &actbytes, data, &cc, &toggle, len, pid, 
+                              urb_state);
+	maxps = usb_maxpacket (urb->dev, urb->pipe, usb_pipeout (urb->pipe));
+
+	if (maxps == 0) 
+            maxps = 8;
+
+	active = (urb_state!=US_CTRL_SETUP) && 
+		(actbytes && !(actbytes & (maxps-1))); 
+
+	/* If the transfer is not bulk in, then it is necessary to get all
+	 * data specify by the urb->transfer_len.
+	 */
+		
+	if (!(usb_pipebulk(urb->pipe) && usb_pipein(urb->pipe)))	
+	    active = active && (urb->transfer_buffer_length != 
+                                urb->actual_length+actbytes);
+
+	if (urb->transfer_buffer_length == urb->actual_length+actbytes)
+	    active = 0;
+
+	if ((cc & (SL11H_STATMASK_ERROR | SL11H_STATMASK_TMOUT | 
+                  SL11H_STATMASK_OVF | SL11H_STATMASK_STALL)) 
+            && !(cc & SL11H_STATMASK_NAK))
+        {
+            if (++urb->error_count > 3)  
+            {
+	        DBGERR ("done_list: excessive error: errcount = 0x%x,
+		         cc = 0x%x\n", urb->error_count, cc);
+		urb_state =0;   
+   		active = 0;
+            }
+	    else
+	    {
+	        DBGERR ("done_list: packet err, cc = 0x%x, " 
+                        " urb->length = 0x%x, actual_len = 0x%x," 
+                        " urb_state =0x%x\n", cc, 
+                        urb->transfer_buffer_length, urb->actual_length, 
+                        urb_state);
+//		if (cc & SL11H_STATMASK_STALL)
+//		{
+		    /* The USB function is STALLED on a control pipe (0), 
+                     * then it needs to send the SETUP command again to 
+                     * clear the STALL condition
+ 		     */
+			
+//                  if (usb_pipeendpoint (urb->pipe) == 0)
+//		    {
+//		        urb_state = 2;	
+//			active = 0;
+//		    }
+//		 }
+//		 else	
+		     active =1;
+		
+            }
+	}
+        else
+        {
+            if (cc & SL11H_STATMASK_NAK) 
+	    {
+	        if (hci->nakCnt < 0x10000)
+	        {
+	            hci->nakCnt++;
+		    hci->last_packet_nak = 1;
+		    active = 1;
+		    *isExcessNak = 0;
+	        }
+	        else
+		{
+		    DBGERR ("done_list: nak count exceed limit\n");
+		    active = 0;
+		    *isExcessNak = 1;
+		    hci->nakCnt=0;
+		}
+	    }
+	    else 
+	    {
+	        hci->nakCnt = 0;
+		hci->last_packet_nak = 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);
+	    }
+ 	}	
+	if (!active)
+	{
+	    if (!urb_state)
+	    {
+		urb->status = cc_to_error(cc);
+		if (urb->status)
+		{
+		    DBGERR ("error on received packet: urb->status = 0x%x\n", 
+						urb->status);
+		}
+		hci->td_array->len = 0;
+		qu_return_urb(hci, urb, 1);
+		return -1;
+	    }
+	    else
+	    {
+	         /* We do not want to decrement the urb_state if exceeded nak,
+		  * because we need to finish the data stage of the control 
+                  * packet 
+                  */
+		
+                 if (!(*isExcessNak))
+		    urb_state--;
+		 qu_seturbstate(urb, urb_state);
+	    }		
+        }
+    }
+
+    if (urb_state < 0)
+	DBGERR ("ERROR: done_list, urb_state = %d, suppose > 0\n", urb_state);
+    if (debugLen != hci->td_array->len)
+    {
+        DBGERR ("ERROR: done_list, debugLen!= td_array->len," 
+                "debugLen = 0x%x, hci->td_array->len = 0x%x\n", 
+                debugLen, hci->td_array->len);
+    }
+    
+    hci->td_array->len = 0;
+	
+    return urb_state;
+}
diff -urN -X dontdiff linux-vanilla/drivers/usb/hc_simple.h linux/drivers/usb/hc_simple.h
--- linux-vanilla/drivers/usb/hc_simple.h	Wed Dec 31 17:00:00 1969
+++ linux/drivers/usb/hc_simple.h	Thu Jan 31 15:41:11 2002
@@ -0,0 +1,282 @@
+/*-------------------------------------------------------------------------*/
+/* list of all controllers using this driver 
+ * */
+ 
+static LIST_HEAD (hci_hcd_list);
+
+
+/* URB states (urb_state) */ 
+/* isoc, interrupt single state */
+
+/* bulk transfer main state and 0-length packet */
+#define US_BULK 	0	 
+#define US_BULK0 	1
+/* three setup states */
+#define US_CTRL_SETUP 	2
+#define US_CTRL_DATA	1
+#define US_CTRL_ACK		0
+
+
+/*-------------------------------------------------------------------------*/
+/* HC private part of a device descriptor
+ * */
+
+#define NUM_EDS 32
+
+typedef struct epd {
+	urb_t * pipe_head;
+	struct list_head urb_queue;
+//	int urb_state;
+	struct timer_list timeout;
+	int last_iso;			/* timestamp of last queued ISOC transfer */
+
+} epd_t;
+
+struct hci_device {
+	epd_t ed [NUM_EDS];
+};
+
+/*-------------------------------------------------------------------------*/
+/* Virtual Root HUB 
+ * */
+
+#define usb_to_hci(usb)	((struct hci_device *)(usb)->hcpriv)
+
+struct virt_root_hub {
+	int devnum; 		/* Address of Root Hub endpoint */ 
+	void * urb;			/* interrupt URB of root hub */
+	int send;			/* active flag */
+ 	int interval;		/* intervall of roothub interrupt transfers */
+	struct timer_list rh_int_timer; /* intervall timer for rh interrupt EP */
+};
+
+#if 1
+/* USB HUB CONSTANTS (not OHCI-specific; see hub.h and USB spec) */
+ 
+/* destination of request */
+#define RH_INTERFACE               0x01
+#define RH_ENDPOINT                0x02
+#define RH_OTHER                   0x03
+
+#define RH_CLASS                   0x20
+#define RH_VENDOR                  0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS           0x0080
+#define RH_CLEAR_FEATURE        0x0100
+#define RH_SET_FEATURE          0x0300
+#define RH_SET_ADDRESS			0x0500
+#define RH_GET_DESCRIPTOR		0x0680
+#define RH_SET_DESCRIPTOR       0x0700
+#define RH_GET_CONFIGURATION	0x0880
+#define RH_SET_CONFIGURATION	0x0900
+#define RH_GET_STATE            0x0280
+#define RH_GET_INTERFACE        0x0A80
+#define RH_SET_INTERFACE        0x0B00
+#define RH_SYNC_FRAME           0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP               0x2000
+
+
+/* Hub port features */

⌨️ 快捷键说明

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