📄 patch-2.4.4-sl811hs
字号:
+ 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 + -