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

📄 patch-2.4.4-sl811hs

📁 基于Linux的USB芯片SL811主机驱动程序,由芯片厂家提供.
💻 4-SL811HS
📖 第 1 页 / 共 5 页
字号:
+	    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 */+#define RH_PORT_CONNECTION         0x00+#define RH_PORT_ENABLE             0x01+#define RH_PORT_SUSPEND            0x02+#define RH_PORT_OVER_CURRENT       0x03+#define RH_PORT_RESET              0x04+#define RH_PORT_POWER              0x08+#define RH_PORT_LOW_SPEED          0x09++#define RH_C_PORT_CONNECTION       0x10+#define RH_C_PORT_ENABLE           0x11+#define RH_C_PORT_SUSPEND          0x12+#define RH_C_PORT_OVER_CURRENT     0x13+#define RH_C_PORT_RESET            0x14  ++/* Hub features */+#define RH_C_HUB_LOCAL_POWER       0x00+#define RH_C_HUB_OVER_CURRENT      0x01++#define RH_DEVICE_REMOTE_WAKEUP    0x00+#define RH_ENDPOINT_STALL          0x01++#endif+++/*-------------------------------------------------------------------------*/+/* struct for each HC + * */++#define MAX_TRANS 32++typedef struct td {+		urb_t * urb; +		__u16 len;+		__u16 iso_index;+} td_t;++typedef struct td_array {+	int len;+	td_t td [MAX_TRANS];+} td_array_t;++typedef struct hci {+	struct virt_root_hub rh;		/* roothub */+	wait_queue_head_t waitq;		/* deletion of URBs and devices needs a waitqueue */+	int active;						/* HC is operating */+	+	struct list_head ctrl_list;		/* set of ctrl endpoints */+	struct list_head bulk_list;		/* set of bulk endpoints */

⌨️ 快捷键说明

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