Author: wmb Date: 2007-12-02 11:27:07 +0100 (Sun, 02 Dec 2007) New Revision: 745
Modified: dev/usb2/hcd/ehci/probe.fth dev/usb2/hcd/hcd.fth dev/usb2/hcd/uhci/bulk.fth dev/usb2/hcd/uhci/probe.fth dev/usb2/hcd/uhci/uhci.fth Log: USB UHCI driver - Several fixes for the UHCI (USB 1.1) driver for compatibility with Intel ICH7 and some full-speed devices.
Modified: dev/usb2/hcd/ehci/probe.fth =================================================================== --- dev/usb2/hcd/ehci/probe.fth 2007-12-02 02:43:57 UTC (rev 744) +++ dev/usb2/hcd/ehci/probe.fth 2007-12-02 10:27:07 UTC (rev 745) @@ -40,6 +40,29 @@ then drop ;
+: grab-controller ( -- error? ) + hccparams@ 8 rshift h# ff and dup if ( config-adr ) + dup my-l@ h# 10001 = if ( config-adr ) + h# 100.0000 over my-l! ( config-adr ) \ Ask for it + true ( config-adr error? ) + d# 100 0 do ( config-adr error? ) + over my-l@ h# 101.0000 and h# 100.0000 = if + \ Turn off SMIs in Legacy Support Extended CSR + h# e000.0000 h# 6c my-l! ( config-adr error? ) + 0 my-l@ h# 27cc8086 = if + h# ffff.0000 h# 70 my-l! \ Clear EHCI Intel special SMIs + then + 0= leave ( config-adr error?' ) + then ( config-adr error? ) + d# 10 ms ( config-adr error? ) + loop ( config-adr error? ) + nip exit + then ( config-adr ) + then ( config-adr ) + drop ( ) + false +; + external : power-usb-ports ( -- ) ;
@@ -64,8 +87,14 @@ parse-my-args open-count 0= if map-regs + alloc-dma-buf first-open? if false to first-open? + grab-controller if + ." Can't take control of EHCI from underlying BIOS" cr + free-dma-buf unmap-regs + false exit + then 0 ehci-reg@ h# ff and to op-reg-offset reset-usb init-ehci-regs @@ -74,8 +103,6 @@ init-struct init-extra then - alloc-dma-buf - probe-root-hub then open-count 1+ to open-count
Modified: dev/usb2/hcd/hcd.fth =================================================================== --- dev/usb2/hcd/hcd.fth 2007-12-02 02:43:57 UTC (rev 744) +++ dev/usb2/hcd/hcd.fth 2007-12-02 10:27:07 UTC (rev 745) @@ -60,6 +60,9 @@ : my-w@ ( offset -- w ) my-space + " config-w@" $call-parent ; : my-w! ( w offset -- ) my-space + " config-w!" $call-parent ;
+: my-l@ ( offset -- l ) my-space + " config-l@" $call-parent ; +: my-l! ( l offset -- ) my-space + " config-l!" $call-parent ; + : map-in ( phys.lo,md,hi len -- vaddr ) " map-in" $call-parent ; : map-out ( vaddr size -- ) " map-out" $call-parent ;
Modified: dev/usb2/hcd/uhci/bulk.fth =================================================================== --- dev/usb2/hcd/uhci/bulk.fth 2007-12-02 02:43:57 UTC (rev 744) +++ dev/usb2/hcd/uhci/bulk.fth 2007-12-02 10:27:07 UTC (rev 745) @@ -103,21 +103,24 @@ bulk-in-qh my-speed insert-bulk-qh ;
+: bulk-in-actual ( -- actual usberr ) + bulk-in-td bulk-in-qh >qh-#tds l@ get-actual ( actual ) + usb-error ( actual usberr ) + bulk-in-td bulk-in-qh >qh-#tds l@ fixup-bulk-in-data +; + : bulk-in? ( -- actual usberr ) bulk-in-qh 0= if 0 USB_ERR_INV_OP exit then clear-usb-error process-hc-status - bulk-in-qh dup sync-qhtds - qh-done? if - bulk-in-td bulk-in-qh >qh-#tds l@ get-actual ( actual ) - usb-error ( actual usberr ) - bulk-in-td bulk-in-qh >qh-#tds l@ fixup-bulk-in-data - else + bulk-in-qh dup sync-qhtds ( bulk-in-qh ) + qh-done? if ( ) + bulk-in-actual ( actual usberr ) + else ( ) bulk-in-qh dup >hcqh-elem le-l@ ( qh elem ) 1 ms over sync-qhtds ( qh elem ) swap >hcqh-elem le-l@ = if \ No movement in the past ms - bulk-in-td bulk-in-qh >qh-#tds l@ get-actual ( actual ) - usb-error ( actual usberr ) + bulk-in-actual ( actual usberr ) bulk-in-td bulk-in-qh >qh-#tds l@ fixup-bulk-in-data else \ It may not be done yet 0 usb-error ( actual usberr ) @@ -130,14 +133,16 @@
headers : restart-bulk-in-td ( td -- ) - begin ?dup while - dup >hctd-token dup le-l@ TD_TOKEN_DATA1 invert and - bulk-in-data@ toggle-bulk-in-data or swap le-l! - dup >hctd-stat dup le-l@ - TD_STAT_ANY_ERROR TD_ACTUAL_MASK or invert and - TD_STAT_ACTIVE or swap le-l! - >td-next l@ - repeat + begin ?dup while ( td ) + toggle-bulk-in-data ( td ) + dup >hctd-token ( td &token ) + dup le-l@ TD_TOKEN_DATA1 invert and ( td &token value ) + bulk-in-data@ or swap le-l! ( td ) + dup >hctd-stat dup le-l@ ( td &stat value ) + TD_STAT_ANY_ERROR TD_ACTUAL_MASK or invert and ( td &stat value' ) + TD_STAT_ACTIVE or swap le-l! ( td ) + >td-next l@ ( td' ) + repeat ( ) ;
external
Modified: dev/usb2/hcd/uhci/probe.fth =================================================================== --- dev/usb2/hcd/uhci/probe.fth 2007-12-02 02:43:57 UTC (rev 744) +++ dev/usb2/hcd/uhci/probe.fth 2007-12-02 10:27:07 UTC (rev 745) @@ -4,17 +4,20 @@ hex headers
+\ We mustn't wait more than 3 ms between releasing the reset and enabling +\ the port to begin the SOF stream, otherwise some devices (e.g. pl2303) +\ will go into suspend state and then not respond to set-address. : reset-root-hub-port ( port -- ) - dup >r portsc@ fff5 and 200 or r@ portsc! \ Reset port - 10 ms - r@ portsc@ fff5 and 200 invert and r@ portsc! - 10 ms - r@ portsc@ fff5 and 4 or r@ portsc! \ Enable port - 20 ms - r@ portsc@ a or r> portsc! \ Clear status + dup >r portsc@ h# 20e invert and ( value r: port ) \ Clear reset, enable, status + dup h# 200 or r@ portsc! ( value r: port ) \ Reset port + d# 30 ms ( value r: port ) \ > 10 ms - reset time + dup r@ portsc! ( value r: port ) \ Release reset + 1 ms ( value r: port ) \ > 5.3 uS - reconnect time + h# e or r> portsc! ( ) \ Enable port and clear status ;
: probe-root-hub-port ( port -- ) + dup reset-root-hub-port dup portsc@ 1 and 0= if drop exit then \ No device-connected ok-to-add-device? 0= if drop exit then \ Can't add another device
@@ -39,7 +42,6 @@ 2 0 do i portsc@ h# a and if i rm-obsolete-children \ Remove obsolete device nodes - i reset-root-hub-port i ['] probe-root-hub-port catch if drop ." Failed to probe root port " i .d cr then @@ -57,6 +59,7 @@ map-regs first-open? if false to first-open? + ?disable-smis reset-usb init-struct init-lists @@ -73,7 +76,7 @@ : close ( -- ) open-count 1- to open-count end-extra - open-count 0= if free-dma-buf unmap-regs then + open-count 0= if free-dma-buf then \ Don't unmap ;
\ LICENSE_BEGIN
Modified: dev/usb2/hcd/uhci/uhci.fth =================================================================== --- dev/usb2/hcd/uhci/uhci.fth 2007-12-02 02:43:57 UTC (rev 744) +++ dev/usb2/hcd/uhci/uhci.fth 2007-12-02 10:27:07 UTC (rev 745) @@ -52,6 +52,10 @@ : portsc@ ( port -- data ) 2* 10 + uhci-w@ ; : portsc! ( data port -- ) 2* 10 + uhci-w! ;
+: ?disable-smis ( -- ) + 0 my-l@ h# 27c88086 = if h# af00 h# 80 my-w! then +; + : reset-usb ( -- ) uhci-reg dup 0= if map-regs then 4 usbcmd! \ Global reset