From e052c5968d6f73da2fe31b1389b52ab307630578 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Mon, 10 Feb 2020 16:23:19 +0100 Subject: [PATCH] Support detecting USB port speeds. --- Cargo.lock | 70 +++++----- xhcid/Cargo.toml | 2 +- xhcid/src/xhci/capability.rs | 16 +++ xhcid/src/xhci/extended.rs | 244 +++++++++++++++++++++++++++++++++- xhcid/src/xhci/mod.rs | 123 ++++++++++++++--- xhcid/src/xhci/operational.rs | 4 + xhcid/src/xhci/port.rs | 8 +- xhcid/src/xhci/scheme.rs | 5 + 8 files changed, 415 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index acf300f158..8da1af7f15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,7 +6,7 @@ version = "0.1.0" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "block-io-wrapper 0.1.0", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "partitionlib 0.1.0 (git+https://gitlab.redox-os.org/redox-os/partitionlib.git)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -49,7 +49,7 @@ name = "base64" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -92,7 +92,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "1.3.2" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -100,7 +100,7 @@ name = "bytes" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -278,7 +278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -301,7 +301,7 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -464,7 +464,7 @@ dependencies = [ [[package]] name = "netutils" version = "0.1.0" -source = "git+https://gitlab.redox-os.org/redox-os/netutils.git#7cfab705109a388c804ae624f8af2d930ab7a06c" +source = "git+https://gitlab.redox-os.org/redox-os/netutils.git#85c159fdd8bbdc562afb5041ae40dde566bed538" dependencies = [ "arg_parser 0.1.0 (git+https://gitlab.redox-os.org/redox-os/arg-parser.git)", "extra 0.1.0 (git+https://gitlab.redox-os.org/redox-os/libextra.git)", @@ -477,7 +477,7 @@ dependencies = [ "redox_event 0.1.0 (git+https://gitlab.redox-os.org/redox-os/event.git)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.13 (git+https://gitlab.redox-os.org/redox-os/tokio)", "tokio-reactor 0.1.7 (git+https://gitlab.redox-os.org/redox-os/tokio)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -497,7 +497,7 @@ dependencies = [ "redox_event 0.1.0 (git+https://gitlab.redox-os.org/redox-os/event.git)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -632,7 +632,7 @@ source = "git+https://github.com/a8m/pb#87c29c05486afa7335916c870ea3621ff7ef2966 dependencies = [ "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -643,7 +643,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -653,7 +653,7 @@ name = "pcid" version = "0.1.0" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -827,7 +827,7 @@ dependencies = [ [[package]] name = "redox_syscall" version = "0.1.56" -source = "git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=dma-slices#13dea70f6bdd09f0128595ebf640e203abff7392" +source = "git+https://gitlab.redox-os.org/redox-os/syscall.git#8d0015be8693a81c2a4459f3c09fb47b98ff07b1" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -932,7 +932,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -994,15 +994,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.44" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1022,7 +1022,7 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1051,12 +1051,12 @@ name = "stb_truetype" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1066,7 +1066,7 @@ dependencies = [ [[package]] name = "termion" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1090,7 +1090,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1302,10 +1302,10 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1462,10 +1462,10 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "redox_event 0.1.0 (git+https://gitlab.redox-os.org/redox-os/event.git)", - "redox_syscall 0.1.56 (git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=dma-slices)", + "redox_syscall 0.1.56 (git+https://gitlab.redox-os.org/redox-os/syscall.git)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1482,7 +1482,7 @@ dependencies = [ "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" -"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" @@ -1505,7 +1505,7 @@ dependencies = [ "checksum hyper-rustls 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "71f7b2e5858ab9e19771dc361159f09ee5031734a6f7471fe0947db0238d92b7" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" @@ -1557,7 +1557,7 @@ dependencies = [ "checksum ransid 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "22b9af151b0590163dfa64e1c92c0831377d61942df4c19820c704390ebc3045" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_event 0.1.0 (git+https://gitlab.redox-os.org/redox-os/event.git)" = "" -"checksum redox_syscall 0.1.56 (git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=dma-slices)" = "" +"checksum redox_syscall 0.1.56 (git+https://gitlab.redox-os.org/redox-os/syscall.git)" = "" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" @@ -1577,16 +1577,16 @@ dependencies = [ "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" +"checksum serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "15913895b61e0be854afd32fd4163fcd2a3df34142cf2cb961b310ce694cbf90" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" -"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4" +"checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" "checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum stb_truetype 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9d1bec4382294c5a680fcebd29f8451e8d8c04479a026f6909004e2ab1cb425d" "checksum stb_truetype 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" -"checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8" -"checksum termion 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "818ef3700c2a7b447dca1a1dd28341fe635e6ee103c806c636bb9c929991b2cd" +"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +"checksum termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905" "checksum thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "205684fd018ca14432b12cce6ea3d46763311a571c3d294e71ba3f01adcf1aad" "checksum thiserror-impl 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57e4d2e50ca050ed44fb58309bdce3efa79948f84f9993ad1978de5eebdce5a7" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" @@ -1608,7 +1608,7 @@ dependencies = [ "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" +"checksum unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" diff --git a/xhcid/Cargo.toml b/xhcid/Cargo.toml index 7a2b3de990..b67f291149 100644 --- a/xhcid/Cargo.toml +++ b/xhcid/Cargo.toml @@ -17,7 +17,7 @@ plain = "0.2" lazy_static = "1.4" spin = "0.4" redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git" } -redox_syscall = { git = "https://gitlab.redox-os.org/4lDO2/syscall.git", branch = "dma-slices" } +redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git" } serde = { version = "1", features = ["derive"] } serde_json = "1" smallvec = { version = "1", features = ["serde"] } diff --git a/xhcid/src/xhci/capability.rs b/xhcid/src/xhci/capability.rs index d79d93d8f2..3654534f18 100644 --- a/xhcid/src/xhci/capability.rs +++ b/xhcid/src/xhci/capability.rs @@ -16,10 +16,17 @@ pub struct CapabilityRegs { pub const HCC_PARAMS1_MAXPSASIZE_MASK: u32 = 0xF000; // 15:12 pub const HCC_PARAMS1_MAXPSASIZE_SHIFT: u8 = 12; +pub const HCC_PARAMS1_XECP_MASK: u32 = 0xFFFF_0000; +pub const HCC_PARAMS1_XECP_SHIFT: u8 = 16; pub const HCC_PARAMS2_LEC_BIT: u32 = 1 << 4; pub const HCC_PARAMS2_CIC_BIT: u32 = 1 << 5; +pub const HCS_PARAMS1_MAX_PORTS_MASK: u32 = 0xFF00_0000; +pub const HCS_PARAMS1_MAX_PORTS_SHIFT: u8 = 24; +pub const HCS_PARAMS1_MAX_SLOTS_MASK: u32 = 0x0000_00FF; +pub const HCS_PARAMS1_MAX_SLOTS_SHIFT: u8 = 0; + impl CapabilityRegs { pub fn lec(&self) -> bool { self.hcc_params2.readf(HCC_PARAMS2_LEC_BIT) @@ -31,4 +38,13 @@ impl CapabilityRegs { ((self.hcc_params1.read() & HCC_PARAMS1_MAXPSASIZE_MASK) >> HCC_PARAMS1_MAXPSASIZE_SHIFT) as u8 } + pub fn max_ports(&self) -> u8 { + ((self.hcs_params1.read() & HCS_PARAMS1_MAX_PORTS_MASK) >> HCS_PARAMS1_MAX_PORTS_SHIFT) as u8 + } + pub fn max_slots(&self) -> u8 { + (self.hcs_params1.read() & HCS_PARAMS1_MAX_SLOTS_MASK) as u8 + } + pub fn ext_caps_ptr_in_dwords(&self) -> u16 { + ((self.hcc_params1.read() & HCC_PARAMS1_XECP_MASK) >> HCC_PARAMS1_XECP_SHIFT) as u16 + } } diff --git a/xhcid/src/xhci/extended.rs b/xhcid/src/xhci/extended.rs index 93962b8347..d444810b86 100644 --- a/xhcid/src/xhci/extended.rs +++ b/xhcid/src/xhci/extended.rs @@ -1,4 +1,54 @@ -use syscall::Mmio; +use std::ops::Range; +use std::ptr::NonNull; +use std::{fmt, mem, ptr, slice}; +use syscall::{Io, Mmio}; + +pub struct ExtendedCapabilitiesIter { + base: *const u8, +} +impl ExtendedCapabilitiesIter { + pub unsafe fn new(base: *const u8) -> Self { + Self { + base, + } + } +} +impl Iterator for ExtendedCapabilitiesIter { + type Item = (NonNull, u8); // pointer, capability id + + fn next(&mut self) -> Option { + unsafe { + let current = NonNull::new(self.base as *mut _)?; + + let reg = current.cast::>().as_ref().read(); + let capability_id = (reg & 0xFF) as u8; + let next_rel_in_dwords = ((reg & 0xFF00) >> 8) as u8; + + let next_rel = u16::from(next_rel_in_dwords) << 2; + + self.base = if next_rel != 0 { self.base.offset(next_rel as isize) } else { ptr::null() }; + + Some((current, capability_id)) + } + } +} + +#[repr(u8)] +pub enum CapabilityId { + // bit 0 is reserved + UsbLegacySupport = 1, + SupportedProtocol, + ExtendedPowerManagement, + IoVirtualization, + MessageInterrupt, + LocalMem, + // bits 7-9 are reserved + UsbDebugCapability = 10, + // bits 11-16 are reserved + ExtendedMessageInterrupt = 17, + // bits 18-191 are reserved + // bits 192-255 are vendor-defined +} #[repr(packed)] pub struct SupportedProtoCap { @@ -6,5 +56,195 @@ pub struct SupportedProtoCap { b: Mmio, c: Mmio, d: Mmio, - protocols: [Mmio], + protocol_speeds: [u8; 0], +} + +#[repr(packed)] +pub struct ProtocolSpeed { + a: Mmio, +} + +pub const PROTO_SPEED_PSIV_MASK: u32 = 0x0000_000F; +pub const PROTO_SPEED_PSIV_SHIFT: u8 = 0; + +pub const PROTO_SPEED_PSIE_MASK: u32 = 0x0000_0030; +pub const PROTO_SPEED_PSIE_SHIFT: u8 = 4; + +pub const PROTO_SPEED_PLT_MASK: u32 = 0x0000_00C0; +pub const PROTO_SPEED_PLT_SHIFT: u8 = 6; + +pub const PROTO_SPEED_PFD_BIT: u32 = 1 << PROTO_SPEED_PFD_SHIFT; +pub const PROTO_SPEED_PFD_SHIFT: u8 = 8; + +pub const PROTO_SPEED_LP_MASK: u32 = 0x0000_C000; +pub const PROTO_SPEED_LP_SHIFT: u8 = 14; + +pub const PROTO_SPEED_PSIM_MASK: u32 = 0xFFFF_0000; +pub const PROTO_SPEED_PSIM_SHIFT: u8 = 16; + +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub enum Psie { + Bps, + Kbps, + Mbps, + Gbps, +} +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum Plt { + Symmetric, + Reserved, + AsymmetricRx, + AsymmetricTx, +} +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum Lp { + SuperSpeed, + SuperSpeedPlus, + Rsvd2, + Rsvd3, +} + +impl ProtocolSpeed { + pub const fn from_raw(raw: u32) -> Self { + Self { + a: Mmio::from(raw), + } + } + pub fn is_lowspeed(&self) -> bool { + self.psim() == 1500 && self.psie() == Psie::Kbps + } + pub fn is_fullspeed(&self) -> bool { + self.psim() == 12 && self.psie() == Psie::Mbps + } + pub fn is_highspeed(&self) -> bool { + self.psim() == 480 && self.psie() == Psie::Mbps + } + /// Protocol speed ID value + pub fn psiv(&self) -> u8 { + ((self.a.read() & PROTO_SPEED_PSIV_MASK) >> PROTO_SPEED_PSIV_SHIFT) as u8 + } + pub fn psie_raw(&self) -> u8 { + ((self.a.read() & PROTO_SPEED_PSIE_MASK) >> PROTO_SPEED_PSIE_SHIFT) as u8 + } + /// Protocol speed ID exponent + pub fn psie(&self) -> Psie { + // safe because psie_raw can only return values in 0..=3 + unsafe { mem::transmute(self.psie_raw()) } + } + pub fn plt_raw(&self) -> u8 { + ((self.a.read() & PROTO_SPEED_PLT_MASK) >> PROTO_SPEED_PLT_SHIFT) as u8 + } + /// PSI type + pub fn plt(&self) -> Plt { + // safe because plt_raw can only return values in 0..=3 + unsafe { mem::transmute(self.plt_raw()) } + } + /// PSI Full-duplex + pub fn pfd(&self) -> bool { + self.a.readf(PROTO_SPEED_PFD_BIT) + } + pub fn lp_raw(&self) -> u8 { + ((self.a.read() & PROTO_SPEED_LP_MASK) >> PROTO_SPEED_LP_SHIFT) as u8 + } + /// Link protocol + pub fn lp(&self) -> Lp { + // safe because lp_raw can only return values in 0..=3 + unsafe { mem::transmute(self.lp_raw()) } + } + /// Protocol speed ID mantissa + pub fn psim(&self) -> u16 { + ((self.a.read() & PROTO_SPEED_PSIM_MASK) >> PROTO_SPEED_PSIM_SHIFT) as u16 + } +} + +impl fmt::Debug for ProtocolSpeed { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("ProtocolSpeed") + .field("psiv", &self.psiv()) + .field("psie", &self.psie()) + .field("plt", &self.plt()) + .field("pfd", &self.pfd()) + .field("lp", &self.lp()) + .field("psim", &self.psim()) + .finish() + } +} + +pub const SUPP_PROTO_CAP_REV_MIN_MASK: u32 = 0x00FF_0000; +pub const SUPP_PROTO_CAP_REV_MIN_SHIFT: u8 = 16; + +pub const SUPP_PROTO_CAP_REV_MAJ_MASK: u32 = 0xFF00_0000; +pub const SUPP_PROTO_CAP_REV_MAJ_SHIFT: u8 = 24; + +pub const SUPP_PROTO_CAP_COMPAT_PORT_OFF_MASK: u32 = 0x0000_00FF; +pub const SUPP_PROTO_CAP_COMPAT_PORT_OFF_SHIFT: u8 = 0; + +pub const SUPP_PROTO_CAP_COMPAT_PORT_CNT_MASK: u32 = 0x0000_FF00; +pub const SUPP_PROTO_CAP_COMPAT_PORT_CNT_SHIFT: u8 = 8; + +pub const SUPP_PROTO_CAP_PROTO_DEF_MASK: u32 = 0x0FFF_0000; +pub const SUPP_PROTO_CAP_PROTO_DEF_SHIFT: u8 = 16; + +pub const SUPP_PROTO_CAP_PSIC_MASK: u32 = 0xF000_0000; +pub const SUPP_PROTO_CAP_PSIC_SHIFT: u8 = 28; + +pub const SUPP_PROTO_CAP_PORT_SLOT_TYPE_MASK: u32 = 0x0000_001F; +pub const SUPP_PROTO_CAP_PORT_SLOT_TYPE_SHIFT: u8 = 0; + +impl SupportedProtoCap { + pub unsafe fn protocol_speeds(&self) -> &[ProtocolSpeed] { + slice::from_raw_parts(&self.protocol_speeds as *const u8 as *const _, self.psic() as usize) + } + pub unsafe fn protocol_speeds_mut(&mut self) -> &mut [ProtocolSpeed] { + // XXX: Variance really is annoying sometimes. + slice::from_raw_parts_mut(&self.protocol_speeds as *const u8 as *mut u8 as *mut _, self.psic() as usize) + } + pub fn rev_minor(&self) -> u8 { + ((self.a.read() & SUPP_PROTO_CAP_REV_MIN_MASK) >> SUPP_PROTO_CAP_REV_MIN_SHIFT) as u8 + } + pub fn rev_major(&self) -> u8 { + ((self.a.read() & SUPP_PROTO_CAP_REV_MAJ_MASK) >> SUPP_PROTO_CAP_REV_MAJ_SHIFT) as u8 + } + pub fn name_string(&self) -> [u8; 4] { + // TODO: Little endian, right? + u32::to_le_bytes(self.b.read()) + } + pub fn compat_port_offset(&self) -> u8 { + ((self.c.read() & SUPP_PROTO_CAP_COMPAT_PORT_OFF_MASK) >> SUPP_PROTO_CAP_COMPAT_PORT_OFF_SHIFT) as u8 + } + pub fn compat_port_count(&self) -> u8 { + ((self.c.read() & SUPP_PROTO_CAP_COMPAT_PORT_CNT_MASK) >> SUPP_PROTO_CAP_COMPAT_PORT_CNT_SHIFT) as u8 + } + pub fn compat_port_range(&self) -> Range { + self.compat_port_offset()..self.compat_port_offset() + self.compat_port_count() + } + + pub fn proto_defined(&self) -> u16 { + ((self.c.read() & SUPP_PROTO_CAP_PROTO_DEF_MASK) >> SUPP_PROTO_CAP_PROTO_DEF_SHIFT) as u16 + } + pub fn psic(&self) -> u8 { + ((self.c.read() & SUPP_PROTO_CAP_PSIC_MASK) >> SUPP_PROTO_CAP_PSIC_SHIFT) as u8 + } + pub fn proto_slot_ty(&self) -> u8 { + ((self.d.read() & SUPP_PROTO_CAP_PORT_SLOT_TYPE_MASK) >> SUPP_PROTO_CAP_PORT_SLOT_TYPE_SHIFT) as u8 + } +} +impl fmt::Debug for SupportedProtoCap { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + + f.debug_struct("SupportedProtoCap") + .field("rev_minor", &self.rev_minor()) + .field("rev_major", &self.rev_major()) + .field("name_string", &String::from_utf8_lossy(&self.name_string())) + .field("compat_port_offset", &self.compat_port_count()) + .field("compat_port_count", &self.compat_port_offset()) + .field("proto_defined", &self.proto_defined()) + .field("psic", &self.psic()) + .field("proto_slot_ty", &self.proto_slot_ty()) + .field("proto_speeds", unsafe { &self.protocol_speeds().to_owned() }) + .finish() + } } diff --git a/xhcid/src/xhci/mod.rs b/xhcid/src/xhci/mod.rs index 77b3150142..a74b7b0c26 100644 --- a/xhcid/src/xhci/mod.rs +++ b/xhcid/src/xhci/mod.rs @@ -1,6 +1,7 @@ use std::collections::BTreeMap; use std::convert::TryFrom; use std::pin::Pin; +use std::ptr::NonNull; use std::sync::{atomic::AtomicBool, Arc, Mutex, Weak}; use std::{mem, process, slice, sync::atomic, task}; @@ -27,6 +28,7 @@ use self::capability::CapabilityRegs; use self::command::CommandRing; use self::context::{DeviceContextList, InputContext, StreamContextArray}; use self::doorbell::Doorbell; +use self::extended::{CapabilityId, ExtendedCapabilitiesIter, ProtocolSpeed, SupportedProtoCap}; use self::operational::OperationalRegs; use self::port::Port; use self::ring::Ring; @@ -117,6 +119,8 @@ pub struct Xhci { dev_ctx: DeviceContextList, cmd: CommandRing, + base: *const u8, + handles: BTreeMap, next_handle: usize, port_states: BTreeMap, @@ -169,10 +173,7 @@ impl Xhci { let op = unsafe { &mut *(op_base as *mut OperationalRegs) }; println!(" - OP {:X}", op_base); - let max_slots; - let max_ports; - - { + let (max_slots, max_ports) = { println!(" - Wait for ready"); // Wait until controller is ready while op.usb_sts.readf(1 << 11) { @@ -196,13 +197,13 @@ impl Xhci { } println!(" - Read max slots"); - // Read maximum slots and ports - let hcs_params1 = cap.hcs_params1.read(); - max_slots = (hcs_params1 & 0xFF) as u8; - max_ports = ((hcs_params1 & 0xFF000000) >> 24) as u8; + + let max_slots = cap.max_slots(); + let max_ports = cap.max_ports(); println!(" - Max Slots: {}, Max Ports {}", max_slots, max_ports); - } + (max_slots, max_ports) + }; let port_base = op_base + 0x400; let ports = @@ -218,11 +219,12 @@ impl Xhci { println!(" - RUNTIME {:X}", run_base); let mut xhci = Xhci { - cap: cap, - op: op, - ports: ports, - dbs: dbs, - run: run, + base: address as *const u8, + cap, + op, + ports, + dbs, + run, dev_ctx: DeviceContextList::new(max_slots)?, cmd: CommandRing::new()?, handles: BTreeMap::new(), @@ -292,6 +294,10 @@ impl Xhci { self.dbs[0].write(0); println!(" - XHCI initialized"); + + for (pointer, capability) in self.capabilities_iter() { + dbg!(pointer, capability); + } } pub fn enable_port_slot(cmd: &mut CommandRing, dbs: &mut [Doorbell]) -> u8 { @@ -345,7 +351,7 @@ impl Xhci { { input.add_context.write(1 << 1 | 1); // Enable the slot (zeroth bit) and the control endpoint (first bit). - input.device.slot.a.write((1 << 27) | (speed << 20)); // FIXME: The speed field, bits 23:20, is deprecated. + input.device.slot.a.write((1 << 27) | (u32::from(speed) << 20)); // FIXME: The speed field, bits 23:20, is deprecated. input.device.slot.b.write(((i as u32 + 1) & 0xFF) << 16); // control endpoint? @@ -494,6 +500,93 @@ impl Xhci { Ok(()) } + pub fn capabilities_iter(&self) -> ExtendedCapabilitiesIter { + unsafe { ExtendedCapabilitiesIter::new((self.base as *mut u8).offset((self.cap.ext_caps_ptr_in_dwords() << 2) as isize)) } + } + pub fn supported_protocols_iter(&self) -> impl Iterator { + self.capabilities_iter().filter_map(|(pointer, cap_num)| unsafe { + if cap_num == CapabilityId::SupportedProtocol as u8 { + Some(&*pointer.cast::().as_ptr()) + } else { + None + } + }) + } + pub fn supported_protocol_speeds(&self, port: u8) -> Option> { + use extended::*; + const DEFAULT_SUPP_PROTO_SPEEDS: [ProtocolSpeed; 7] = [ + // Full-speed + ProtocolSpeed::from_raw( + (Plt::Symmetric as u32) << PROTO_SPEED_PLT_SHIFT + | (false as u32) << PROTO_SPEED_PFD_SHIFT + | (Psie::Mbps as u32) << PROTO_SPEED_PSIE_SHIFT + | 12 << PROTO_SPEED_PSIM_SHIFT + | 1 << PROTO_SPEED_PSIV_SHIFT + ), + // Low-speed + ProtocolSpeed::from_raw( + (Plt::Symmetric as u32) << PROTO_SPEED_PLT_SHIFT + | (false as u32) << PROTO_SPEED_PFD_SHIFT + | (Psie::Kbps as u32) << PROTO_SPEED_PSIE_SHIFT + | 1500 << PROTO_SPEED_PSIM_SHIFT + | 2 << PROTO_SPEED_PSIV_SHIFT + ), + // High-speed + ProtocolSpeed::from_raw( + (Plt::Symmetric as u32) << PROTO_SPEED_PLT_SHIFT + | (false as u32) << PROTO_SPEED_PFD_SHIFT + | (Psie::Mbps as u32) << PROTO_SPEED_PSIE_SHIFT + | 480 << PROTO_SPEED_PSIM_SHIFT + | 3 << PROTO_SPEED_PSIV_SHIFT + ), + // SuperSpeed Gen1 x1 + ProtocolSpeed::from_raw( + (Plt::Symmetric as u32) << PROTO_SPEED_PLT_SHIFT + | (true as u32) << PROTO_SPEED_PFD_SHIFT + | (Psie::Gbps as u32) << PROTO_SPEED_PSIE_SHIFT + | 5 << PROTO_SPEED_PSIM_SHIFT + | (Lp::SuperSpeed as u32) << PROTO_SPEED_LP_SHIFT + | 4 << PROTO_SPEED_PSIV_SHIFT + ), + // SuperSpeedPlus Gen2 x1 + ProtocolSpeed::from_raw( + (Plt::Symmetric as u32) << PROTO_SPEED_PLT_SHIFT + | (true as u32) << PROTO_SPEED_PFD_SHIFT + | (Psie::Gbps as u32) << PROTO_SPEED_PSIE_SHIFT + | 10 << PROTO_SPEED_PSIM_SHIFT + | (Lp::SuperSpeedPlus as u32) << PROTO_SPEED_LP_SHIFT + | 5 << PROTO_SPEED_PSIV_SHIFT + ), + // SuperSpeedPlus Gen1 x2 + ProtocolSpeed::from_raw( + (Plt::Symmetric as u32) << PROTO_SPEED_PLT_SHIFT + | (true as u32) << PROTO_SPEED_PFD_SHIFT + | (Psie::Gbps as u32) << PROTO_SPEED_PSIE_SHIFT + | 10 << PROTO_SPEED_PSIM_SHIFT + | (Lp::SuperSpeedPlus as u32) << PROTO_SPEED_LP_SHIFT + | 6 << PROTO_SPEED_PSIV_SHIFT + ), + // SuperSpeedPlus Gen2 x2 + ProtocolSpeed::from_raw( + (Plt::Symmetric as u32) << PROTO_SPEED_PLT_SHIFT + | (true as u32) << PROTO_SPEED_PFD_SHIFT + | (Psie::Gbps as u32) << PROTO_SPEED_PSIE_SHIFT + | 20 << PROTO_SPEED_PSIM_SHIFT + | (Lp::SuperSpeedPlus as u32) << PROTO_SPEED_LP_SHIFT + | 7 << PROTO_SPEED_PSIV_SHIFT + ), + ]; + let supp_proto = self.supported_protocols_iter().find(|supp_proto| supp_proto.compat_port_range().contains(&port))?; + + Some(if supp_proto.psic() != 0 { + unsafe { supp_proto.protocol_speeds().iter() } + } else { + DEFAULT_SUPP_PROTO_SPEEDS.iter() + }) + } + pub fn lookup_psiv(&self, port: u8, psiv: u8) -> Option<&'static ProtocolSpeed> { + self.supported_protocol_speeds(port)?.find(|speed| speed.psiv() == psiv) + } } #[derive(Deserialize)] struct DriverConfig { diff --git a/xhcid/src/xhci/operational.rs b/xhcid/src/xhci/operational.rs index d7cc3dfc1a..638f210333 100644 --- a/xhcid/src/xhci/operational.rs +++ b/xhcid/src/xhci/operational.rs @@ -1,5 +1,9 @@ +use std::slice; +use std::num::NonZeroU8; use syscall::io::{Io, Mmio}; +use super::CapabilityRegs; + #[repr(packed)] pub struct OperationalRegs { pub usb_cmd: Mmio, diff --git a/xhcid/src/xhci/port.rs b/xhcid/src/xhci/port.rs index 1745a793bd..674a79332a 100644 --- a/xhcid/src/xhci/port.rs +++ b/xhcid/src/xhci/port.rs @@ -39,12 +39,12 @@ impl Port { self.portsc.read() } - pub fn state(&self) -> u32 { - (self.read() & (0b1111 << 5)) >> 5 + pub fn state(&self) -> u8 { + ((self.read() & (0b1111 << 5)) >> 5) as u8 } - pub fn speed(&self) -> u32 { - (self.read() & (0b1111 << 10)) >> 10 + pub fn speed(&self) -> u8 { + ((self.read() & (0b1111 << 10)) >> 10) as u8 } pub fn flags(&self) -> PortFlags { diff --git a/xhcid/src/xhci/scheme.rs b/xhcid/src/xhci/scheme.rs index 098c9d4670..51633331e6 100644 --- a/xhcid/src/xhci/scheme.rs +++ b/xhcid/src/xhci/scheme.rs @@ -239,6 +239,11 @@ impl Xhci { return Err(Error::new(EBADMSG)); } + let port_speed_id = self.ports[port].speed(); + // FIXME + let speed_id = self.lookup_psiv(port as u8, port_speed_id); + dbg!(speed_id); + let port_state = self.port_states.get_mut(&port).ok_or(Error::new(ENOENT))?; let input_context: &mut Dma = &mut port_state.input_context;