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