📄 patch-2.4.4-sl811hs
字号:
++void regShow(hci_t *hci)+{+ int i;+ for (i = 0; i<256; i++)+ {+ printk ("offset %d: 0x%x\n", i, SL811Read(hci, i));+ }+} ++/************************************************************************+ * Function Name : USBReset+ * + * This function resets SL811HS controller and detects the speed of+ * the connecting device + *+ * Input: hci = data structure for the host controller+ * + * Return: 0 = no device attached; 1 = USB device attached+ * + ***********************************************************************/++static int USBReset (hci_t *hci)+{+ int status ;+ hcipriv_t *hp = &hci->hp; ++ DBGFUNC ("enter USBReset\n"); + ++ SL811Write(hci, SL11H_CTLREG2, 0xae);++ // setup master and full speed+ + SL811Write(hci, SL11H_CTLREG1, 0x08 ); // reset USB+ mdelay(20); // 20ms + SL811Write(hci, SL11H_CTLREG1, 0); // remove SE0 ++ for (status=0; status < 100; status++)+ SL811Write (hci, SL11H_INTSTATREG, 0xff); // clear all interrupt bits++ status = SL811Read (hci, SL11H_INTSTATREG);++ if (status & 0x40) // Check if device is removed+ {+ DBG ("USBReset: Device removed\n");+ SL811Write(hci, SL11H_INTENBLREG, SL11H_INTMASK_XFERDONE + | SL11H_INTMASK_SOFINTR|SL11H_INTMASK_INSRMV); + hp->RHportStatus->portStatus &= ~(PORT_CONNECT_STAT | PORT_ENABLE_STAT);+ + return 0;+ }+ + SL811Write (hci, SL11H_BUFLNTHREG_B, 0 ) ; //zero lenth+ SL811Write (hci, SL11H_PIDEPREG_B, 0x50 ) ; //send SOF to EP0 + SL811Write (hci, SL11H_DEVADDRREG_B, 0x01 ) ; //address0+ SL811Write (hci, SL11H_SOFLOWREG, 0xe0 ) ;++ if (!(status & 0x80 ))+ { + /* slow speed device connect directly to root-hub */+ + DBG ("USBReset: low speed Device attached\n");+ SL811Write (hci, SL11H_CTLREG1, 0x8);+ mdelay(20);+ SL811Write (hci, SL11H_SOFTMRREG, 0xee ); + SL811Write (hci, SL11H_CTLREG1, 0x21 );+ + /* start the SOF or EOP */+ + SL811Write (hci, SL11H_HOSTCTLREG_B, 0x01 ) ; + hp->RHportStatus->portStatus |= (PORT_CONNECT_STAT + | PORT_LOW_SPEED_DEV_ATTACH_STAT);+ + /* clear all interrupt bits */+ + for (status=0; status < 20; status++)+ SL811Write (hci, SL11H_INTSTATREG, 0xff); + }+ else+ { + /* full speed device connect directly to root hub */+ + DBG ("USBReset: full speed Device attached\n");+ SL811Write (hci, SL11H_CTLREG1, 0x8);+ mdelay(20);+ SL811Write (hci, SL11H_SOFTMRREG, 0xae ) ;+ SL811Write (hci, SL11H_CTLREG1, 0x01 ) ; ++ /* start the SOF or EOP */+ + SL811Write (hci, SL11H_HOSTCTLREG_B, 0x01 ) ; + hp->RHportStatus->portStatus |= (PORT_CONNECT_STAT);+ hp->RHportStatus->portStatus &= ~PORT_LOW_SPEED_DEV_ATTACH_STAT; + + /* clear all interrupt bits */++ SL811Write (hci, SL11H_INTSTATREG, 0xff); ++ }+ + /* enable all interrupts */ ++ SL811Write(hci, SL11H_INTENBLREG, SL11H_INTMASK_XFERDONE + | SL11H_INTMASK_SOFINTR|SL11H_INTMASK_INSRMV);++ return 1;+}++/*-------------------------------------------------------------------------*/+/* tl functions */+static inline void hc_mark_last_trans (hci_t * hci) +{+ hcipriv_t * hp = &hci->hp; + __u8 * ptd = hp->tl;+ + dbg ("enter hc_mark_last_trans\n");+ if (ptd == NULL)+ {+ printk ("hc_mark_last_trans: ptd = null\n");+ return;+ }+ if (hp->xferPktLen > 0)+ *(ptd + hp->tl_last) |= (1 << 3);+}++static inline void hc_flush_data_cache (hci_t * hci, void * data, int len) +{}+++/************************************************************************+ * Function Name : hc_add_trans+ * + * This function sets up the SL811HS register and transmit the USB packets.+ * + * 1) Determine if enough time within the current frame to send the packet+ * 2) Load the data into the SL811HS register+ * 3) Set the appropriate command to the register and trigger the transmit+ *+ * Input: hci = data structure for the host controller+ * len = data length+ * data = transmitting data+ * toggle = USB toggle bit, either 0 or 1+ * maxps = maximum packet size for this endpoint+ * slow = speed of the device+ * endpoint = endpoint number+ * address = USB address of the device+ * pid = packet ID+ * format = + * urb_state = the current stage of USB transaction+ * + * Return: 0 = no time left to schedule the transfer+ * 1 = success + * + ***********************************************************************/++static inline int hc_add_trans (hci_t * hci, int len, void * data,+ int toggle, int maxps, int slow, int endpoint, int address, int pid, int format, int urb_state)+{+ hcipriv_t * hp = &hci->hp; + __u16 speed;+ int ii, jj, kk;+ + DBGFUNC ("enter hc_addr_trans: len =0x%x, toggle:0x%x, endpoing:0x%x," + " addr:0x%x, pid:0x%x,format:0x%x\n", len, toggle, endpoint, i+ address, pid, format);+ + if (len > maxps)+ {+ len = maxps;+ }++ speed = hp->RHportStatus->portStatus;+ if (speed & PORT_LOW_SPEED_DEV_ATTACH_STAT)+ {+// ii = (8*7*8 + 6*3) * len + 800; + ii = 8*8*len + 1024; + }+ else+ {+ if (slow)+ {+// ii = (8*7*8 + 6*3) * len + 800; + ii = 8*8*len + 2048;+ }+ else +// ii = (8*7 + 6*3)*len + 110;+ ii = 8*len + 256;+ }++ ii += 2*10 * len;+++ jj = SL811Read(hci, SL11H_SOFTMRREG);+ kk = (jj & 0xFF) * 64 - ii;++ if (kk < 0)+ {+ DBGVERBOSE ("hc_add_trans: no bandwidth for schedule, ii = 0x%x," + "jj = 0x%x, len =0x%x, active_trans = 0x%x\n", ii, jj, + len, hci->active_trans);+ return (-1);+ } ++ if (pid != PID_IN) + {+ /* Load data into hc */++ SL811BufWrite(hci, SL11H_DATA_START, (__u8 *) data, len);+ } + + /* transmit */++ SL11StartXaction(hci, (__u8) address, (__u8) endpoint, + (__u8) pid, len, toggle, slow, urb_state);++ return len;+}+++/************************************************************************+ * Function Name : hc_parse_trans+ * + * This function checks the status of the transmitted or received packet+ * and copy the data from the SL811HS register into a buffer.+ *+ * 1) Check the status of the packet + * 2) If successful, and IN packet then copy the data from the SL811HS register+ * into a buffer+ *+ * Input: hci = data structure for the host controller+ * actbytes = pointer to actual number of bytes+ * data = data buffer+ * cc = packet status+ * length = the urb transmit length+ * pid = packet ID+ * urb_state = the current stage of USB transaction+ * + * Return: 0 + ***********************************************************************/++static inline int hc_parse_trans (hci_t * hci, int * actbytes, __u8 * data, + int * cc, int * toggle, int length, int pid, int urb_state)+{+ __u8 addr;+ __u8 len;++ DBGFUNC ("enter hc_parse_trans\n");+ + /* get packet status; convert ack rcvd to ack-not-rcvd */++ *cc = (int) SL811Read(hci, SL11H_PKTSTATREG);+++ if (*cc & (SL11H_STATMASK_ERROR | SL11H_STATMASK_TMOUT | + SL11H_STATMASK_OVF | SL11H_STATMASK_NAK | SL11H_STATMASK_STALL))+ {+ if (*cc & SL11H_STATMASK_OVF)+ DBGERR ("parse trans: error recv ack, cc = 0x%x, TX_BASE_Len = "+ "0x%x, TX_count=0x%x\n", *cc, + SL811Read(hci, SL11H_BUFLNTHREG), + SL811Read(hci, SL11H_XFERCNTREG));+ + }+ else + {+ DBGVERBOSE ("parse trans: recv ack, cc = 0x%x, len = 0x%x, \n", + *cc, length);+ + /* Successful data */++ if ((pid == PID_IN) && (urb_state != US_CTRL_SETUP))+ {++ /* Find the base address */+ + addr = SL811Read(hci, SL11H_BUFADDRREG);++ /* Find the Transmit Length */+ + len = SL811Read(hci, SL11H_BUFLNTHREG);++ /* The actual data length = xmit length reg - xfer count reg */++ *actbytes = len - SL811Read(hci, SL11H_XFERCNTREG);++ if ((data != NULL) && (*actbytes > 0))+ {+ SL811BufRead (hci, addr, data, *actbytes); + + }+ else if ((data == NULL) && (*actbytes <=0))+ { + DBGERR ("hc_parse_trans: data = NULL or actbyte = 0x%x\n", + *actbytes);+ return 0;+ }+ }+ else if (pid == PID_OUT)+ {+ *actbytes = length;+ }+ else+ {+ // printk ("ERR:parse_trans, pid != IN or OUT, pid = 0x%x\n", pid);+ } + *toggle = !*toggle;+ } + + return 0;+}++/************************************************************************+ * Function Name : hc_start_int+ * + * This function enables SL811HS interrupts+ *+ * Input: hci = data structure for the host controller+ * + * Return: none + ***********************************************************************/++static void hc_start_int (hci_t *hci)+{+#ifdef HC_SWITCH_INT + int mask = SL11H_INTMASK_XFERDONE | SL11H_INTMASK_SOFINTR |+ SL11H_INTMASK_INSRMV | SL11H_INTMASK_USBRESET;+ SL811Write (hci, IntEna, mask); +#endif+} ++/************************************************************************+ * Function Name : hc_stop_int+ * + * This function disables SL811HS interrupts+ *+ * Input: hci = data structure for the host controller+ * + * Return: none + ***********************************************************************/++static void hc_stop_int (hci_t *hci)+{+#ifdef HC_SWITCH_INT+ SL811Write(hci, SL11H_INTSTATREG, 0xff); +// SL811Write(hci, SL11H_INTENBLREG, SL11H_INTMASK_INSRMV);++#endif+}+++/************************************************************************+ * Function Name : handleInsRmvIntr+ * + * This function handles the insertion or removal of device on SL811HS. + * It resets the controller and updates the port status+ *+ * Input: hci = data structure for the host controller+ * + * Return: none + ***********************************************************************/++void handleInsRmvIntr (hci_t * hci)+{+ hcipriv_t * hp = &hci->hp; ++ USBReset(hci);+ + /* Changes in connection status */++ hp->RHportStatus->portChange |= PORT_CONNECT_CHANGE;++ /* Port Enable or Disable */++ if (hp->RHportStatus->portStatus & PORT_CONNECT_STAT)+ {+ /* device is connected to the port:+ * 1) Enable port + * 2) Resume ?? + */+// hp->RHportStatus->portChange |= PORT_ENABLE_CHANGE;++ /* Over Current is not supported by the SL811 HW ?? */++ /* How about the Port Power ?? */++ }+ else+ {+ /* Device has disconnect:+ * 1) Disable port+ */++ hp->RHportStatus->portStatus &= ~(PORT_ENABLE_STAT);+ hp->RHportStatus->portChange |= PORT_ENABLE_CHANGE;+ + + }+}++/*****************************************************************+ *+ * Function Name: SL11StartXaction+ * + * This functions load the registers with appropriate value and + * transmit the packet. + *+ * Input: hci = data structure for the host controller+ * addr = USB address of the device+ * epaddr = endpoint number+ * pid = packet ID+ * len = data length+ * toggle = USB toggle bit, either 0 or 1+ * slow = speed of the device+ * urb_state = the current stage of USB transaction+ *+ * Return: 0 = error; 1 = successful+ * + *****************************************************************/++int SL11StartXaction(hci_t *hci, __u8 addr, __u8 epaddr, int pid, int len, + int toggle, int slow, int urb_state)+{+ + hcipriv_t * hp = &hci->hp; + __u8 cmd = 0;+ __u8 setup_data[4];+ __u16 speed;++ speed = hp->RHportStatus->portStatus;+ if (!(speed & PORT_LOW_SPEED_DEV_ATTACH_STAT) && slow)+ {+ cmd |= SL11H_HCTLMASK_PREAMBLE; + }+ switch (pid)+ {+ case PID_SETUP:+ cmd &= SL11H_HCTLMASK_PREAMBLE;+ cmd |= (SL11H_HCTLMASK_ARM | SL11H_HCTLMASK_ENBLEP + | SL11H_HCTLMASK_WRITE);+ break;++ case PID_OUT:+ cmd &= (SL11H_HCTLMASK_SEQ | SL11H_HCTLMASK_PREAMBLE);+ cmd |= (SL11H_HCTLMASK_ARM | SL11H_HCTLMASK
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -