[openfirmware] r1651 - in dev/usb2/hcd: . ehci
svn at openfirmware.info
svn at openfirmware.info
Fri Jan 8 08:30:03 CET 2010
Author: wmb
Date: 2010-01-08 08:30:03 +0100 (Fri, 08 Jan 2010)
New Revision: 1651
Modified:
dev/usb2/hcd/dev-info.fth
dev/usb2/hcd/ehci/bulk.fth
dev/usb2/hcd/ehci/control.fth
dev/usb2/hcd/ehci/intr.fth
dev/usb2/hcd/ehci/probe.fth
dev/usb2/hcd/ehci/qhtd.fth
Log:
OLPC trac 9969 - make USB work after resume - sort of. USB 2.0 devices
like mass storage devices and LANs work after resume, so long as you
don't suspend/resume too many times. Eventually the system dies with
"user area used up", because the device nodes get reloaded every time.
I need to work out how to reuse the device nodes instead of reloading,
but that could get complicated. I also need to do something about USB 1.1
devices.
Modified: dev/usb2/hcd/dev-info.fth
===================================================================
--- dev/usb2/hcd/dev-info.fth 2010-01-08 07:23:30 UTC (rev 1650)
+++ dev/usb2/hcd/dev-info.fth 2010-01-08 07:30:03 UTC (rev 1651)
@@ -25,9 +25,9 @@
1+ \ Padding for word alignment
/di-ep-struct #max-endpoint * field >di-ep
\ Endpoint structure
-dup constant /di-entry
+constant /di-entry
-#max-dev * constant /di
+/di-entry #max-dev * constant /di
0 value di \ device-info
0 value cur-dev \ Value of the last assigned usb address
@@ -60,14 +60,17 @@
;
: init-di ( -- )
- \ allocate and initialize the device descriptors
- /di alloc-mem to di
- di /di erase
- /pipe0 0 0 di-maxpayload! \ Default max payload
+ di 0= if
+ \ allocate and initialize the device descriptors
+ /di alloc-mem to di
+ di /di erase
+ /pipe0 0 0 di-maxpayload! \ Default max payload
+ then
;
: init-struct ( -- )
init-di
+ 0 to cur-dev
;
headers
Modified: dev/usb2/hcd/ehci/bulk.fth
===================================================================
--- dev/usb2/hcd/ehci/bulk.fth 2010-01-08 07:23:30 UTC (rev 1650)
+++ dev/usb2/hcd/ehci/bulk.fth 2010-01-08 07:30:03 UTC (rev 1651)
@@ -76,9 +76,9 @@
then ( #qtds )
bulk-qh reuse-qhqtds
;
-: free-bulk-qhqtds ( -- )
+: free-bulk-qh ( -- )
bulk-qh ?dup if ( qh )
- free-qhqtds ( )
+ free-qh ( )
0 to bulk-qh
then
;
@@ -512,7 +512,7 @@
headers
-: (end-extra) ( -- ) end-bulk-in free-bulk-qhqtds ;
+: (end-extra) ( -- ) end-bulk-in free-bulk-qh ;
\ LICENSE_BEGIN
Modified: dev/usb2/hcd/ehci/control.fth
===================================================================
--- dev/usb2/hcd/ehci/control.fth 2010-01-08 07:23:30 UTC (rev 1650)
+++ dev/usb2/hcd/ehci/control.fth 2010-01-08 07:30:03 UTC (rev 1651)
@@ -149,7 +149,7 @@
then
then
- my-qh dup remove-qh free-qhqtds ( actual )
+ my-qh dup remove-qh free-qh ( actual )
usb-error ( actual usberr )
;
@@ -161,7 +161,7 @@
\ Process results
my-qh done? 0= if my-qh error? drop then
- my-qh dup remove-qh free-qhqtds
+ my-qh dup remove-qh free-qh
usb-error
;
Modified: dev/usb2/hcd/ehci/intr.fth
===================================================================
--- dev/usb2/hcd/ehci/intr.fth 2010-01-08 07:23:30 UTC (rev 1650)
+++ dev/usb2/hcd/ehci/intr.fth 2010-01-08 07:30:03 UTC (rev 1651)
@@ -112,7 +112,7 @@
intr-in-qh 0= if exit then
intr-in-qh dup fixup-intr-in-data
intr-in-qtd map-out-bptrs
- dup remove-intr-qh free-qhqtds
+ dup remove-intr-qh free-qh
0 to intr-in-qh 0 to intr-in-qtd
;
Modified: dev/usb2/hcd/ehci/probe.fth
===================================================================
--- dev/usb2/hcd/ehci/probe.fth 2010-01-08 07:23:30 UTC (rev 1650)
+++ dev/usb2/hcd/ehci/probe.fth 2010-01-08 07:30:03 UTC (rev 1651)
@@ -134,6 +134,17 @@
probe-teardown
;
+: do-resume ( -- )
+ init-ehci-regs
+ start-usb
+ claim-ownership
+ init-struct
+ init-extra
+;
+
+\ This is a sneaky way to determine if the hardware has been turned off without the software's knowledge
+: suspended? ( -- flag ) asynclist@ 0= qh-ptr 0<> and ;
+
: open ( -- flag )
parse-my-args
open-count 0= if
@@ -148,25 +159,15 @@
then
0 ehci-reg@ h# ff and to op-reg-offset
reset-usb
- init-ehci-regs
- start-usb
- claim-ownership
- init-struct
- init-extra
+ do-resume
then
+ suspended? if do-resume then
probe-root-hub
then
open-count 1+ to open-count
true
;
-: do-resume ( -- )
- init-ehci-regs
- start-usb
- claim-ownership
- framelist-phys periodic!
-;
-
: close ( -- )
open-count 1- to open-count
end-extra
Modified: dev/usb2/hcd/ehci/qhtd.fth
===================================================================
--- dev/usb2/hcd/ehci/qhtd.fth 2010-01-08 07:23:30 UTC (rev 1650)
+++ dev/usb2/hcd/ehci/qhtd.fth 2010-01-08 07:30:03 UTC (rev 1651)
@@ -47,14 +47,16 @@
: framelist! ( n idx -- ) 4 * framelist + le-l! ;
: init-framelist ( -- )
- \ Allocate framelist
- /framelist /align4kb aligned-alloc ( unaligned virt )
- swap to framelist-unaligned ( virt )
- dup to framelist ( virt )
- /framelist true dma-map-in to framelist-phys ( )
+ framelist 0= if
+ \ Allocate framelist
+ /framelist /align4kb aligned-alloc ( unaligned virt )
+ swap to framelist-unaligned ( virt )
+ dup to framelist ( virt )
+ /framelist true dma-map-in to framelist-phys ( )
- \ Initialize framelist
- #framelist 0 do TERMINATE i framelist! loop
+ \ Initialize framelist
+ #framelist 0 do TERMINATE i framelist! loop
+ then
framelist-phys periodic!
;
@@ -77,8 +79,10 @@
: intr-tail! ( adr idx -- ) 'intr >intr-tail l! ;
: init-intr ( -- )
- /intr alloc-mem dup to intr \ Allocate intr
- /intr erase \ Initialize intr
+ intr 0= if
+ /intr alloc-mem dup to intr \ Allocate intr
+ /intr erase \ Initialize intr
+ then
;
\ ---------------------------------------------------------------------------
@@ -283,17 +287,8 @@
r> 4 pick link-qhqtds ( qh qtd )
;
-: free-qh ( qh -- )
- >r ( R: qh )
- r@ >qh-unaligned l@ ( qh.u ) ( R: qh )
- r@ dup >qh-phys l@ ( qh.u,v,p ) ( R: qh )
- r> >qh-size l@ ( qh.u,v,p size )
- aligned32-free-map-out ( )
-;
+\ Qtds will be freed automatically when the qh is freed
-\ Same as free-qh because the size field tells all
-: free-qhqtds ( qh -- ) free-qh ;
-
: reuse-qhqtds ( #qtds qh -- qh qtd )
swap dup >r /qtd * /qh + >r ( qh ) ( R: #qtds len )
dup >qh-unaligned l@ swap ( qh.u,v ) ( R: #qtds len )
@@ -367,36 +362,41 @@
usbcmd@ h# 20 and 5 >> usbsts@ h# 8000 and d# 15 >>
= until
;
-: enable-async ( phys -- )
- asynclist! async-wait
+: enable-async ( qh -- )
+ >qh-phys l@ asynclist! async-wait
usbcmd@ h# 20 or usbcmd! async-wait
;
: disable-async ( -- )
async-wait usbcmd@ h# 20 invert and usbcmd! async-wait
+ 0 to qh-ptr
;
+: link-to-qh-ptr ( qh -- )
+ dup qh-ptr >qh-next l! ( qh )
+ dup >qh-phys l@ TYP_QH or qh-ptr >hcqh-next le-l! ( qh )
+ sync-qhqtds ( )
+;
: insert-qh ( qh -- )
- >r
- qh-ptr if
- \ If there is another qh in the system, link the new qh to the existing
- \ qh head.
- qh-ptr r@ >qh-prev l!
- qh-ptr >qh-next l@ r@ >qh-next l!
- qh-ptr >hcqh-next le-l@ r@ >hcqh-next le-l!
- r@ qh-ptr >qh-next l!
- r@ >qh-phys l@ TYP_QH or qh-ptr >hcqh-next le-l!
+ qh-ptr if ( qh )
+ \ If there is another qh, link the new qh to the existing qh head.
+ qh-ptr over >qh-prev l! ( qh )
+ qh-ptr >qh-next l@ over >qh-next l! ( qh )
+ qh-ptr >hcqh-next le-l@ over >hcqh-next le-l! ( qh )
- r> sync-qhqtds
- qh-ptr sync-qh
- else
- \ If there is no qh in the system, link it to itself and mark it the
- \ head.
- r@ to qh-ptr
- r@ >hcqh-endp-char dup le-l@ QH_HEAD or swap le-l!
- r@ dup >qh-next l!
- r@ >qh-phys l@ dup TYP_QH or r@ >hcqh-next le-l!
- r> sync-qhqtds
- enable-async
+ link-to-qh-ptr ( )
+
+ qh-ptr sync-qh ( )
+ else ( )
+ \ If there is no other qh, make it the head, link it to itself,
+ \ and start the asynch schedule.
+
+ to qh-ptr ( )
+
+ qh-ptr >hcqh-endp-char dup le-l@ QH_HEAD or swap le-l! ( )
+
+ qh-ptr link-to-qh-ptr ( )
+
+ qh-ptr enable-async ( )
then
;
: fix-wraparound-qh ( qh -- )
@@ -423,7 +423,6 @@
dup >qh-next l@ over = if
\ If qh is the only qh in the system, disable-async and exit
drop disable-async
- 0 to qh-ptr
else
\ Otherwise, qh.prev points to qh.next, fix up reclamation bits.
\ Ring doorbell, wait for answer.
@@ -625,17 +624,20 @@
drop to dummy-qh
TERMINATE dummy-qh >hcqh-overlay >hcqtd-next le-l!
then
+ 0 to qh-ptr
dummy-qh insert-qh
;
: free-dummy-qh ( -- )
- dummy-qh ?dup if free-qhqtds 0 to dummy-qh then
+ dummy-qh ?dup if free-qh 0 to dummy-qh then
;
: ?alloc-dummy-qh ( -- )
0 my-w@ h# 1106 ( VIA ) = if alloc-dummy-qh then
;
+\ The words this calls are written so they can be called again
+\ on resume from S3 state without causing redundant memory allocation.
: (init-extra) ( -- )
?alloc-dummy-qh
init-intr
More information about the openfirmware
mailing list