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