Browse Source

Plan 9 from Bell Labs 2006-06-28

David du Colombier 18 years ago
parent
commit
8fd20e14fd

+ 21 - 21
dist/replica/_plan9.db

@@ -299,7 +299,7 @@
 386/bin/ip/httpd/webls - 775 sys sys 1148500658 133642
 386/bin/ip/httpd/wikipost - 775 sys sys 1148500658 115002
 386/bin/ip/httpfile - 775 sys sys 1148500659 284317
-386/bin/ip/imap4d - 775 sys sys 1148500660 238064
+386/bin/ip/imap4d - 775 sys sys 1151463461 238064
 386/bin/ip/ipconfig - 775 sys sys 1148500661 139400
 386/bin/ip/ping - 775 sys sys 1148500661 76814
 386/bin/ip/ppp - 775 sys sys 1148500662 220485
@@ -12345,7 +12345,7 @@ sys/src/cmd/ip/imap4d - 20000000775 sys sys 988249981 0
 sys/src/cmd/ip/imap4d/auth.c - 664 sys sys 1015013075 3510
 sys/src/cmd/ip/imap4d/copy.c - 664 sys sys 1062298855 4597
 sys/src/cmd/ip/imap4d/csquery.c - 664 sys sys 1015013076 762
-sys/src/cmd/ip/imap4d/date.c - 664 sys sys 1130945828 5684
+sys/src/cmd/ip/imap4d/date.c - 664 sys sys 1151455743 5684
 sys/src/cmd/ip/imap4d/debug.c - 664 sys sys 1016731557 1962
 sys/src/cmd/ip/imap4d/fetch.c - 664 sys sys 1066325855 11762
 sys/src/cmd/ip/imap4d/fns.h - 664 sys sys 1015013076 4282
@@ -14320,21 +14320,21 @@ sys/src/fs - 20000000775 sys sys 1015110109 0
 sys/src/fs/9netics32.16k - 20000000775 sys sys 1140158691 0
 sys/src/fs/9netics32.16k/9net32.16kfs.c - 664 sys sys 1140167903 3208
 sys/src/fs/9netics32.16k/dat.h - 664 sys sys 1140167904 612
-sys/src/fs/9netics32.16k/fns.h - 664 sys sys 1140167905 1961
+sys/src/fs/9netics32.16k/fns.h - 664 sys sys 1141028463 2127
 sys/src/fs/9netics32.16k/io.h - 664 sys sys 1097661949 6688
 sys/src/fs/9netics32.16k/mem.h - 664 sys sys 1140167906 2907
 sys/src/fs/9netics32.16k/mkfile - 664 sys sys 1140167908 1615
 sys/src/fs/9netics64.8k - 20000000775 sys sys 1140158692 0
 sys/src/fs/9netics64.8k/9net64.8kfs.c - 664 sys sys 1140167920 3235
 sys/src/fs/9netics64.8k/dat.h - 664 sys sys 1095751680 611
-sys/src/fs/9netics64.8k/fns.h - 664 sys sys 1140167922 1961
+sys/src/fs/9netics64.8k/fns.h - 664 sys sys 1141028463 2127
 sys/src/fs/9netics64.8k/io.h - 664 sys sys 1097661949 6688
 sys/src/fs/9netics64.8k/mem.h - 664 sys sys 1140167924 2907
 sys/src/fs/9netics64.8k/mkfile - 664 sys sys 1140167925 1608
 sys/src/fs/choline - 20000000775 sys sys 1015110109 0
 sys/src/fs/choline/9cholinefs.c - 664 sys sys 1140168020 2989
 sys/src/fs/choline/dat.h - 664 sys sys 1140168017 612
-sys/src/fs/choline/fns.h - 664 sys sys 1140168018 1961
+sys/src/fs/choline/fns.h - 664 sys sys 1141028463 2127
 sys/src/fs/choline/io.h - 664 sys sys 1140168018 6688
 sys/src/fs/choline/mem.h - 664 sys sys 1140168019 2909
 sys/src/fs/choline/mkfile - 664 sys sys 1140168021 1751
@@ -14355,24 +14355,24 @@ sys/src/fs/doc/worms.32-bit - 664 sys sys 1140168032 2806
 sys/src/fs/emelie - 20000000775 sys sys 1015110098 0
 sys/src/fs/emelie/9emeliefs.c - 664 sys sys 1140168026 2989
 sys/src/fs/emelie/dat.h - 664 sys sys 1140168023 612
-sys/src/fs/emelie/fns.h - 664 sys sys 1140168023 1961
+sys/src/fs/emelie/fns.h - 664 sys sys 1141028463 2127
 sys/src/fs/emelie/io.h - 664 sys sys 1140168024 6688
 sys/src/fs/emelie/mem.h - 664 sys sys 1140168025 2909
 sys/src/fs/emelie/mkfile - 664 sys sys 1140168027 1750
 sys/src/fs/fs - 20000000775 sys sys 1140158693 0
 sys/src/fs/fs/9fsfs.c - 664 sys sys 1140168015 3308
 sys/src/fs/fs/dat.h - 664 sys sys 1140168010 611
-sys/src/fs/fs/fns.h - 664 sys sys 1140168011 1961
+sys/src/fs/fs/fns.h - 664 sys sys 1141028463 2127
 sys/src/fs/fs/io.h - 664 sys sys 1097661949 6688
 sys/src/fs/fs/mem.h - 664 sys sys 1140168013 2909
 sys/src/fs/fs/mkfile - 664 sys sys 1140168014 1663
 sys/src/fs/fs64 - 20000000775 sys sys 1140158693 0
-sys/src/fs/fs64/9fsfs64.c - 664 sys sys 1140168004 3294
+sys/src/fs/fs64/9fsfs64.c - 664 sys sys 1151399221 3612
 sys/src/fs/fs64/dat.h - 664 sys sys 1140168005 611
-sys/src/fs/fs64/fns.h - 664 sys sys 1140168005 1961
+sys/src/fs/fs64/fns.h - 664 sys sys 1151312486 2289
 sys/src/fs/fs64/io.h - 664 sys sys 1140168006 6688
-sys/src/fs/fs64/mem.h - 664 sys sys 1020579319 2909
-sys/src/fs/fs64/mkfile - 664 sys sys 1140168008 1603
+sys/src/fs/fs64/mem.h - 664 sys sys 1151398965 3041
+sys/src/fs/fs64/mkfile - 664 sys sys 1151403428 1603
 sys/src/fs/ip - 20000000775 sys sys 1015109990 0
 sys/src/fs/ip/arp.c - 664 sys sys 1097578954 8696
 sys/src/fs/ip/icmp.c - 664 sys sys 1015109981 991
@@ -14415,13 +14415,13 @@ sys/src/fs/pc/malloc.c - 664 sys sys 1096789023 2840
 sys/src/fs/pc/mkfile - 664 sys sys 1140167942 426
 sys/src/fs/pc/mmu.c - 664 sys sys 1015110065 8414
 sys/src/fs/pc/nvr.c - 664 sys sys 1015110066 669
-sys/src/fs/pc/pc.c - 664 sys sys 1146785006 7996
-sys/src/fs/pc/pci.c - 664 sys sys 1094949424 12118
+sys/src/fs/pc/pc.c - 664 sys sys 1151401114 8004
+sys/src/fs/pc/pci.c - 664 sys sys 1151280674 12152
 sys/src/fs/pc/script.i - 664 sys sys 1015110072 27323
-sys/src/fs/pc/scsi.c - 664 sys sys 1091803674 8661
+sys/src/fs/pc/scsi.c - 664 sys sys 1151385561 8701
 sys/src/fs/pc/scsibuslogic.c - 664 sys sys 1015110077 28645
 sys/src/fs/pc/scsincr53c8xx.c - 664 sys sys 1146798658 53619
-sys/src/fs/pc/sdata.c - 664 sys sys 1097712291 61793
+sys/src/fs/pc/sdata.c - 664 sys sys 1151401574 63100
 sys/src/fs/pc/sdscsi.c - 664 sys sys 1146786984 7017
 sys/src/fs/pc/toy.c - 664 sys sys 1140167948 2166
 sys/src/fs/pc/trap.c - 664 sys sys 1055699801 7946
@@ -14435,25 +14435,25 @@ sys/src/fs/port/auth.c - 664 sys sys 1146785221 7606
 sys/src/fs/port/chk.c - 664 sys sys 1097832483 15683
 sys/src/fs/port/clock.c - 664 sys sys 1097580538 4033
 sys/src/fs/port/con.c - 664 sys sys 1146785256 16304
-sys/src/fs/port/config.c - 664 sys sys 1107835943 20264
+sys/src/fs/port/config.c - 664 sys sys 1151037810 20380
 sys/src/fs/port/console.c - 664 sys sys 1101627646 4886
 sys/src/fs/port/data.c - 664 sys sys 1140167986 4510
 sys/src/fs/port/dentry.c - 664 sys sys 1098156404 6345
 sys/src/fs/port/devcons.c - 664 sys sys 1095983755 4451
-sys/src/fs/port/devsd.c - 664 sys sys 1097712378 10993
+sys/src/fs/port/devsd.c - 664 sys sys 1151402825 15117
 sys/src/fs/port/fcmd.c - 664 sys sys 1146785267 1255
 sys/src/fs/port/fs.h - 664 sys sys 1140168001 682
 sys/src/fs/port/iobuf.c - 664 sys sys 1140167988 4956
 sys/src/fs/port/lib.h - 664 sys sys 1146798595 3791
 sys/src/fs/port/lrand.c - 664 sys sys 1091803568 1093
-sys/src/fs/port/main.c - 664 sys sys 1140167990 7639
+sys/src/fs/port/main.c - 664 sys sys 1151376423 7827
 sys/src/fs/port/mkfile - 664 sys sys 1140167991 214
-sys/src/fs/port/portdat.h - 664 sys sys 1140163786 19670
+sys/src/fs/port/portdat.h - 664 sys sys 1151312767 19739
 sys/src/fs/port/portfns.h - 664 sys sys 1140167994 7526
 sys/src/fs/port/print.c - 664 sys sys 1015110022 153
 sys/src/fs/port/proc.c - 664 sys sys 1097580775 5364
-sys/src/fs/port/sd.h - 664 sys sys 1097577251 2167
-sys/src/fs/port/sub.c - 664 sys sys 1146787681 25595
+sys/src/fs/port/sd.h - 664 sys sys 1140774087 2305
+sys/src/fs/port/sub.c - 664 sys sys 1151402558 25666
 sys/src/fs/port/time.c - 664 sys sys 1140167998 6222
 sys/src/fs/port/uidgid.c - 664 sys sys 1097574050 9192
 sys/src/games - 20000000775 sys sys 1095792091 0

+ 21 - 21
dist/replica/plan9.db

@@ -299,7 +299,7 @@
 386/bin/ip/httpd/webls - 775 sys sys 1148500658 133642
 386/bin/ip/httpd/wikipost - 775 sys sys 1148500658 115002
 386/bin/ip/httpfile - 775 sys sys 1148500659 284317
-386/bin/ip/imap4d - 775 sys sys 1148500660 238064
+386/bin/ip/imap4d - 775 sys sys 1151463461 238064
 386/bin/ip/ipconfig - 775 sys sys 1148500661 139400
 386/bin/ip/ping - 775 sys sys 1148500661 76814
 386/bin/ip/ppp - 775 sys sys 1148500662 220485
@@ -12345,7 +12345,7 @@ sys/src/cmd/ip/imap4d - 20000000775 sys sys 988249981 0
 sys/src/cmd/ip/imap4d/auth.c - 664 sys sys 1015013075 3510
 sys/src/cmd/ip/imap4d/copy.c - 664 sys sys 1062298855 4597
 sys/src/cmd/ip/imap4d/csquery.c - 664 sys sys 1015013076 762
-sys/src/cmd/ip/imap4d/date.c - 664 sys sys 1130945828 5684
+sys/src/cmd/ip/imap4d/date.c - 664 sys sys 1151455743 5684
 sys/src/cmd/ip/imap4d/debug.c - 664 sys sys 1016731557 1962
 sys/src/cmd/ip/imap4d/fetch.c - 664 sys sys 1066325855 11762
 sys/src/cmd/ip/imap4d/fns.h - 664 sys sys 1015013076 4282
@@ -14320,21 +14320,21 @@ sys/src/fs - 20000000775 sys sys 1015110109 0
 sys/src/fs/9netics32.16k - 20000000775 sys sys 1140158691 0
 sys/src/fs/9netics32.16k/9net32.16kfs.c - 664 sys sys 1140167903 3208
 sys/src/fs/9netics32.16k/dat.h - 664 sys sys 1140167904 612
-sys/src/fs/9netics32.16k/fns.h - 664 sys sys 1140167905 1961
+sys/src/fs/9netics32.16k/fns.h - 664 sys sys 1141028463 2127
 sys/src/fs/9netics32.16k/io.h - 664 sys sys 1097661949 6688
 sys/src/fs/9netics32.16k/mem.h - 664 sys sys 1140167906 2907
 sys/src/fs/9netics32.16k/mkfile - 664 sys sys 1140167908 1615
 sys/src/fs/9netics64.8k - 20000000775 sys sys 1140158692 0
 sys/src/fs/9netics64.8k/9net64.8kfs.c - 664 sys sys 1140167920 3235
 sys/src/fs/9netics64.8k/dat.h - 664 sys sys 1095751680 611
-sys/src/fs/9netics64.8k/fns.h - 664 sys sys 1140167922 1961
+sys/src/fs/9netics64.8k/fns.h - 664 sys sys 1141028463 2127
 sys/src/fs/9netics64.8k/io.h - 664 sys sys 1097661949 6688
 sys/src/fs/9netics64.8k/mem.h - 664 sys sys 1140167924 2907
 sys/src/fs/9netics64.8k/mkfile - 664 sys sys 1140167925 1608
 sys/src/fs/choline - 20000000775 sys sys 1015110109 0
 sys/src/fs/choline/9cholinefs.c - 664 sys sys 1140168020 2989
 sys/src/fs/choline/dat.h - 664 sys sys 1140168017 612
-sys/src/fs/choline/fns.h - 664 sys sys 1140168018 1961
+sys/src/fs/choline/fns.h - 664 sys sys 1141028463 2127
 sys/src/fs/choline/io.h - 664 sys sys 1140168018 6688
 sys/src/fs/choline/mem.h - 664 sys sys 1140168019 2909
 sys/src/fs/choline/mkfile - 664 sys sys 1140168021 1751
@@ -14355,24 +14355,24 @@ sys/src/fs/doc/worms.32-bit - 664 sys sys 1140168032 2806
 sys/src/fs/emelie - 20000000775 sys sys 1015110098 0
 sys/src/fs/emelie/9emeliefs.c - 664 sys sys 1140168026 2989
 sys/src/fs/emelie/dat.h - 664 sys sys 1140168023 612
-sys/src/fs/emelie/fns.h - 664 sys sys 1140168023 1961
+sys/src/fs/emelie/fns.h - 664 sys sys 1141028463 2127
 sys/src/fs/emelie/io.h - 664 sys sys 1140168024 6688
 sys/src/fs/emelie/mem.h - 664 sys sys 1140168025 2909
 sys/src/fs/emelie/mkfile - 664 sys sys 1140168027 1750
 sys/src/fs/fs - 20000000775 sys sys 1140158693 0
 sys/src/fs/fs/9fsfs.c - 664 sys sys 1140168015 3308
 sys/src/fs/fs/dat.h - 664 sys sys 1140168010 611
-sys/src/fs/fs/fns.h - 664 sys sys 1140168011 1961
+sys/src/fs/fs/fns.h - 664 sys sys 1141028463 2127
 sys/src/fs/fs/io.h - 664 sys sys 1097661949 6688
 sys/src/fs/fs/mem.h - 664 sys sys 1140168013 2909
 sys/src/fs/fs/mkfile - 664 sys sys 1140168014 1663
 sys/src/fs/fs64 - 20000000775 sys sys 1140158693 0
-sys/src/fs/fs64/9fsfs64.c - 664 sys sys 1140168004 3294
+sys/src/fs/fs64/9fsfs64.c - 664 sys sys 1151399221 3612
 sys/src/fs/fs64/dat.h - 664 sys sys 1140168005 611
-sys/src/fs/fs64/fns.h - 664 sys sys 1140168005 1961
+sys/src/fs/fs64/fns.h - 664 sys sys 1151312486 2289
 sys/src/fs/fs64/io.h - 664 sys sys 1140168006 6688
-sys/src/fs/fs64/mem.h - 664 sys sys 1020579319 2909
-sys/src/fs/fs64/mkfile - 664 sys sys 1140168008 1603
+sys/src/fs/fs64/mem.h - 664 sys sys 1151398965 3041
+sys/src/fs/fs64/mkfile - 664 sys sys 1151403428 1603
 sys/src/fs/ip - 20000000775 sys sys 1015109990 0
 sys/src/fs/ip/arp.c - 664 sys sys 1097578954 8696
 sys/src/fs/ip/icmp.c - 664 sys sys 1015109981 991
@@ -14415,13 +14415,13 @@ sys/src/fs/pc/malloc.c - 664 sys sys 1096789023 2840
 sys/src/fs/pc/mkfile - 664 sys sys 1140167942 426
 sys/src/fs/pc/mmu.c - 664 sys sys 1015110065 8414
 sys/src/fs/pc/nvr.c - 664 sys sys 1015110066 669
-sys/src/fs/pc/pc.c - 664 sys sys 1146785006 7996
-sys/src/fs/pc/pci.c - 664 sys sys 1094949424 12118
+sys/src/fs/pc/pc.c - 664 sys sys 1151401114 8004
+sys/src/fs/pc/pci.c - 664 sys sys 1151280674 12152
 sys/src/fs/pc/script.i - 664 sys sys 1015110072 27323
-sys/src/fs/pc/scsi.c - 664 sys sys 1091803674 8661
+sys/src/fs/pc/scsi.c - 664 sys sys 1151385561 8701
 sys/src/fs/pc/scsibuslogic.c - 664 sys sys 1015110077 28645
 sys/src/fs/pc/scsincr53c8xx.c - 664 sys sys 1146798658 53619
-sys/src/fs/pc/sdata.c - 664 sys sys 1097712291 61793
+sys/src/fs/pc/sdata.c - 664 sys sys 1151401574 63100
 sys/src/fs/pc/sdscsi.c - 664 sys sys 1146786984 7017
 sys/src/fs/pc/toy.c - 664 sys sys 1140167948 2166
 sys/src/fs/pc/trap.c - 664 sys sys 1055699801 7946
@@ -14435,25 +14435,25 @@ sys/src/fs/port/auth.c - 664 sys sys 1146785221 7606
 sys/src/fs/port/chk.c - 664 sys sys 1097832483 15683
 sys/src/fs/port/clock.c - 664 sys sys 1097580538 4033
 sys/src/fs/port/con.c - 664 sys sys 1146785256 16304
-sys/src/fs/port/config.c - 664 sys sys 1107835943 20264
+sys/src/fs/port/config.c - 664 sys sys 1151037810 20380
 sys/src/fs/port/console.c - 664 sys sys 1101627646 4886
 sys/src/fs/port/data.c - 664 sys sys 1140167986 4510
 sys/src/fs/port/dentry.c - 664 sys sys 1098156404 6345
 sys/src/fs/port/devcons.c - 664 sys sys 1095983755 4451
-sys/src/fs/port/devsd.c - 664 sys sys 1097712378 10993
+sys/src/fs/port/devsd.c - 664 sys sys 1151402825 15117
 sys/src/fs/port/fcmd.c - 664 sys sys 1146785267 1255
 sys/src/fs/port/fs.h - 664 sys sys 1140168001 682
 sys/src/fs/port/iobuf.c - 664 sys sys 1140167988 4956
 sys/src/fs/port/lib.h - 664 sys sys 1146798595 3791
 sys/src/fs/port/lrand.c - 664 sys sys 1091803568 1093
-sys/src/fs/port/main.c - 664 sys sys 1140167990 7639
+sys/src/fs/port/main.c - 664 sys sys 1151376423 7827
 sys/src/fs/port/mkfile - 664 sys sys 1140167991 214
-sys/src/fs/port/portdat.h - 664 sys sys 1140163786 19670
+sys/src/fs/port/portdat.h - 664 sys sys 1151312767 19739
 sys/src/fs/port/portfns.h - 664 sys sys 1140167994 7526
 sys/src/fs/port/print.c - 664 sys sys 1015110022 153
 sys/src/fs/port/proc.c - 664 sys sys 1097580775 5364
-sys/src/fs/port/sd.h - 664 sys sys 1097577251 2167
-sys/src/fs/port/sub.c - 664 sys sys 1146787681 25595
+sys/src/fs/port/sd.h - 664 sys sys 1140774087 2305
+sys/src/fs/port/sub.c - 664 sys sys 1151402558 25666
 sys/src/fs/port/time.c - 664 sys sys 1140167998 6222
 sys/src/fs/port/uidgid.c - 664 sys sys 1097574050 9192
 sys/src/games - 20000000775 sys sys 1095792091 0

+ 26 - 0
dist/replica/plan9.log

@@ -30152,3 +30152,29 @@
 1150203675 0 c lib/face/48x48x4/.dict - 664 sys sys 1150202436 3276
 1150218079 0 c 386/bin/aux/consolefs - 775 sys sys 1150217767 156373
 1150857061 0 c sys/games/lib/fortunes - 664 sys sys 1150855959 259748
+1151400617 0 c sys/src/fs/9netics32.16k/fns.h - 664 sys sys 1141028463 2127
+1151400617 1 c sys/src/fs/9netics64.8k/fns.h - 664 sys sys 1141028463 2127
+1151400617 2 c sys/src/fs/choline/fns.h - 664 sys sys 1141028463 2127
+1151400617 3 c sys/src/fs/emelie/fns.h - 664 sys sys 1141028463 2127
+1151400617 4 c sys/src/fs/fs/fns.h - 664 sys sys 1141028463 2127
+1151400617 5 c sys/src/fs/fs64/9fsfs64.c - 664 sys sys 1151399221 3612
+1151400617 6 c sys/src/fs/fs64/fns.h - 664 sys sys 1151312486 2289
+1151400617 7 c sys/src/fs/fs64/mem.h - 664 sys sys 1151398965 3041
+1151400617 8 c sys/src/fs/fs64/mkfile - 664 sys sys 1140911236 1617
+1151400617 9 c sys/src/fs/pc/pc.c - 664 sys sys 1151400464 7997
+1151400617 10 c sys/src/fs/pc/pci.c - 664 sys sys 1151280674 12152
+1151400617 11 c sys/src/fs/pc/scsi.c - 664 sys sys 1151385561 8701
+1151400617 12 c sys/src/fs/port/devsd.c - 664 sys sys 1151371646 15110
+1151402417 0 c sys/src/fs/pc/pc.c - 664 sys sys 1151401114 8004
+1151402417 1 c sys/src/fs/pc/sdata.c - 664 sys sys 1151401574 63100
+1151402417 2 a sys/src/fs/pc/sdmv50xx.c - 664 sys sys 1151401913 0
+1151402417 3 c sys/src/fs/port/config.c - 664 sys sys 1151037810 20380
+1151402417 4 c sys/src/fs/port/main.c - 664 sys sys 1151376423 7827
+1151402417 5 c sys/src/fs/port/portdat.h - 664 sys sys 1151312767 19739
+1151402417 6 c sys/src/fs/port/sd.h - 664 sys sys 1140774087 2305
+1151404218 0 c sys/src/fs/fs64/mkfile - 664 sys sys 1151403428 1603
+1151404218 1 c sys/src/fs/port/devsd.c - 664 sys sys 1151402825 15117
+1151404218 2 c sys/src/fs/port/sub.c - 664 sys sys 1151402558 25666
+1151404218 3 d sys/src/fs/pc/sdmv50xx.c - 664 sys sys 1151401913 0
+1151456435 0 c sys/src/cmd/ip/imap4d/date.c - 664 sys sys 1151455743 5684
+1151463637 0 c 386/bin/ip/imap4d - 775 sys sys 1151463461 238064

+ 1 - 1
sys/src/cmd/ip/imap4d/date.c

@@ -131,7 +131,7 @@ date2tm(Tm *tm, char *date)
 		return nil;
 
 	if(n == 5){
-		for(n = 5; n >= 0; n--)
+		for(n = 5; n >= 1; n--)
 			flds[n] = flds[n - 1];
 		n = 5;
 	}else{

+ 7 - 0
sys/src/fs/9netics32.16k/fns.h

@@ -73,7 +73,14 @@ void	cpuid(char*, int*, int*);
 
 #define PADDR(a)	((ulong)(a)&~KZERO)
 
+/* pata */
 void	ideinit(Device *d);
 Devsize	idesize(Device *d);
 int	ideread(Device *d,  Devsize, void*);
 int	idewrite(Device *d, Devsize, void*);
+
+/* sata */
+void	mvideinit(Device *d);
+Devsize	mvidesize(Device *d);
+int	mvideread(Device *d,  Devsize, void*);
+int	mvidewrite(Device *d, Devsize, void*);

+ 7 - 0
sys/src/fs/9netics64.8k/fns.h

@@ -73,7 +73,14 @@ void	cpuid(char*, int*, int*);
 
 #define PADDR(a)	((ulong)(a)&~KZERO)
 
+/* pata */
 void	ideinit(Device *d);
 Devsize	idesize(Device *d);
 int	ideread(Device *d,  Devsize, void*);
 int	idewrite(Device *d, Devsize, void*);
+
+/* sata */
+void	mvideinit(Device *d);
+Devsize	mvidesize(Device *d);
+int	mvideread(Device *d,  Devsize, void*);
+int	mvidewrite(Device *d, Devsize, void*);

+ 7 - 0
sys/src/fs/choline/fns.h

@@ -73,7 +73,14 @@ void	cpuid(char*, int*, int*);
 
 #define PADDR(a)	((ulong)(a)&~KZERO)
 
+/* pata */
 void	ideinit(Device *d);
 Devsize	idesize(Device *d);
 int	ideread(Device *d,  Devsize, void*);
 int	idewrite(Device *d, Devsize, void*);
+
+/* sata */
+void	mvideinit(Device *d);
+Devsize	mvidesize(Device *d);
+int	mvideread(Device *d,  Devsize, void*);
+int	mvidewrite(Device *d, Devsize, void*);

+ 7 - 0
sys/src/fs/emelie/fns.h

@@ -73,7 +73,14 @@ void	cpuid(char*, int*, int*);
 
 #define PADDR(a)	((ulong)(a)&~KZERO)
 
+/* pata */
 void	ideinit(Device *d);
 Devsize	idesize(Device *d);
 int	ideread(Device *d,  Devsize, void*);
 int	idewrite(Device *d, Devsize, void*);
+
+/* sata */
+void	mvideinit(Device *d);
+Devsize	mvidesize(Device *d);
+int	mvideread(Device *d,  Devsize, void*);
+int	mvidewrite(Device *d, Devsize, void*);

+ 7 - 0
sys/src/fs/fs/fns.h

@@ -73,7 +73,14 @@ void	cpuid(char*, int*, int*);
 
 #define PADDR(a)	((ulong)(a)&~KZERO)
 
+/* pata */
 void	ideinit(Device *d);
 Devsize	idesize(Device *d);
 int	ideread(Device *d,  Devsize, void*);
 int	idewrite(Device *d, Devsize, void*);
+
+/* sata */
+void	mvideinit(Device *d);
+Devsize	mvidesize(Device *d);
+int	mvideread(Device *d,  Devsize, void*);
+int	mvidewrite(Device *d, Devsize, void*);

+ 21 - 8
sys/src/fs/fs64/9fsfs64.c

@@ -5,6 +5,9 @@
 
 #include "../pc/dosfs.h"
 
+void	apcinit(void);
+int	sdinit(void);
+
 /*
  * setting this to zero permits the use of discs of different sizes, but
  * can make jukeinit() quite slow while the robotics work through each disc
@@ -34,14 +37,13 @@ static struct
 	Off	(*write)(int, void*, long);
 	int	(*part)(int, char*);
 } nvrdevs[] = {
-	{ "fd", floppyread, floppyseek, floppywrite, 0, },
-	{ "hd", ataread,   ataseek,   atawrite,   setatapart, },
-	/* { "sd", scsiread,   scsiseek,   scsiwrite,   setscsipart, },  */
+	{ "fd", floppyread,	floppyseek,	floppywrite, 0, },
+	{ "hd", ataread,	ataseek,	atawrite,	setatapart, },
+	{ "md", mvsataread,	mvsataseek,	mvsatawrite,	setmv50part, },
+/*	{ "sd", scsiread,	scsiseek,	scsiwrite,	setscsipart, },  */
 	{ 0, },
 };
 
-void apcinit(void);
-
 void
 otherinit(void)
 {
@@ -55,7 +57,9 @@ otherinit(void)
 	apcinit();
 
 	s = spllo();
-	nhd = atainit();
+	sdinit();
+	nhd = atainit();	/* harmless to call again */
+	mvsatainit();		/* harmless to call again */
 	nfd = floppyinit();
 	dev = 0;
 	if(p = getconf("nvr")){
@@ -94,7 +98,8 @@ otherinit(void)
 	for(i = 0; nvrdevs[i].name; i++){
 		if(strcmp(p, nvrdevs[i].name) == 0){
 			dos.dev = dev;
-			if(nvrdevs[i].part && (*nvrdevs[i].part)(dos.dev, "disk") == 0)
+			if (nvrdevs[i].part &&
+			    (*nvrdevs[i].part)(dos.dev, "disk") == 0)
 				break;
 			dos.read = nvrdevs[i].read;
 			dos.seek = nvrdevs[i].seek;
@@ -103,12 +108,18 @@ otherinit(void)
 		}
 	}
 	if(dos.read == 0)
-		panic("no device for nvram\n");
+		panic("no device (%s) for nvram\n", p);
 	if(dosinit(&dos) < 0)
 		panic("can't init dos dosfs on %s\n", p);
 	splx(s);
 }
 
+static int
+isdawn(void *)
+{
+	return predawn == 0;
+}
+
 void
 touser(void)
 {
@@ -117,6 +128,8 @@ touser(void)
 	settime(rtctime());
 	boottime = time();
 
+	/* wait for predawn to change to zero to avoid confusing print */
+	sleep(&dawnrend, isdawn, 0);
 	print("sysinit\n");
 	sysinit();
 

+ 12 - 0
sys/src/fs/fs64/fns.h

@@ -73,7 +73,19 @@ void	cpuid(char*, int*, int*);
 
 #define PADDR(a)	((ulong)(a)&~KZERO)
 
+/* pata */
 void	ideinit(Device *d);
 Devsize	idesize(Device *d);
 int	ideread(Device *d,  Devsize, void*);
 int	idewrite(Device *d, Devsize, void*);
+
+/* marvell sata */
+void	mvideinit(Device *d);
+Devsize	mvidesize(Device *d);
+int	mvideread(Device *d,  Devsize, void*);
+int	mvidewrite(Device *d, Devsize, void*);
+int	mvsatainit(void);
+Off	mvsataread(int, void*, long);
+Devsize	mvsataseek(int, Devsize);
+Off	mvsatawrite(int, void*, long);
+int	setmv50part(int, char*);

+ 15 - 11
sys/src/fs/fs64/mem.h

@@ -13,16 +13,20 @@
 /*
  * Fundamental addresses
  */
-#define IDTADDR		0x80000800		/* idt */
-#define APBOOTSTRAP	0x80001000		/* AP bootstrap code */
-#define CONFADDR	0x80001200		/* info passed from boot loader */
-#define CPU0PDB		0x80002000		/* bootstrap processor PDB */
-#define CPU0PTE		0x80003000		/* bootstrap processor PTE's for 0-2MB */
-#define CPU0MACHPTE	0x80004000		/* bootstrap processor PTE for MACHADDR */
-#define CPU0MACH	0x80005000		/* Mach for bootstrap processor */
+/*
+ * KZERO == 0 or 0x80000000 will work fine.  0x10000000 will work but limit
+ * usable memory to 256MB.
+ */
+#define	KZERO		0x80000000	/* base of kernel address space */
+#define	KTZERO		(KZERO+0x100000) /* first address in kernel text */
 
-#define	KZERO		0x80000000		/* base of kernel address space */
-#define	KTZERO		0x80100000		/* first address in kernel text */
+#define IDTADDR		(KZERO+0x800)	/* idt */
+#define APBOOTSTRAP	(KZERO+0x1000)	/* AP bootstrap code */
+#define CONFADDR	(KZERO+0x1200)	/* info passed from boot loader */
+#define CPU0PDB		(KZERO+0x2000)	/* bootstrap processor PDB */
+#define CPU0PTE		(KZERO+0x3000)	/* bootstrap processor PTE's for 0-2MB */
+#define CPU0MACHPTE	(KZERO+0x4000)	/* bootstrap processor PTE for MACHADDR */
+#define CPU0MACH	(KZERO+0x5000)	/* Mach for bootstrap processor */
 
 #define	MACHSIZE	4096
 
@@ -31,7 +35,7 @@
  */
 #define	NULLSEG	0	/* null segment */
 #define	KDSEG	1	/* kernel data/stack */
-#define	KESEG	2	/* kernel executable */	
+#define	KESEG	2	/* kernel executable */
 #define	UDSEG	3	/* user data/stack */
 #define	UESEG	4	/* user executable */
 #define TSSSEG	5	/* task segment */
@@ -73,7 +77,7 @@
  *  physical MMU
  */
 #define	PTEVALID	(1<<0)
-#define	PTEUNCACHED	(1<<4)	
+#define	PTEUNCACHED	(1<<4)
 #define PTEWRITE	(1<<1)
 #define	PTERONLY	(0<<1)
 #define	PTEKERNEL	(0<<2)

+ 4 - 3
sys/src/fs/pc/pc.c

@@ -168,9 +168,10 @@ getconf(char *name)
 	return 0;
 }
 
-/* memory map */
-/* the file server kernel will only see MAXMEG megabytes of RAM at most.  */
-#define MAXMEG 1791		/* 1.75GB-1MB, to avoid overshooting 1.75GB */
+/* memory map; this kernel will see MAXMEG megabytes of RAM at most.  */
+#ifndef MAXMEG
+#define MAXMEG 1791	/* 1.75GB-1MB, to avoid overshooting into PCI space */
+#endif
 
 char mmap[MAXMEG+2];
 Mconf mconf;

+ 2 - 0
sys/src/fs/pc/pci.c

@@ -535,6 +535,8 @@ vid2name(int vid)
 		return "neomagic";	/* or magicgraph */
 	case 0x10de:
 		return "nvidia";
+	case 0x11ab:
+		return "marvell";
 	case 0x11ad:
 		return "(pnic?)";
 	case 0x121a:

+ 8 - 5
sys/src/fs/pc/scsi.c

@@ -53,9 +53,10 @@ cmd_stat(int, char*[])
 			tp = &ctlr->target[targetno];
 			if(tp->fflag == 0)
 				continue;
-			print("	%d.%d work =%7W%7W%7W pkts\n", ctlrno, targetno,
+			print("\t%d.%d work =%7W%7W%7W xfrs\n",
+				ctlrno, targetno,
 				tp->work+0, tp->work+1, tp->work+2);
-			print("	    rate =%7W%7W%7W tBps\n",
+			print("\t    rate =%7W%7W%7W tBps\n",
 				tp->rate+0, tp->rate+1, tp->rate+2);
 		}
 	}
@@ -373,12 +374,14 @@ scsiio(Device* d, int rw, uchar* cmd, int cbytes, void* data, int dbytes)
 	if(tp->ok == 0)
 		scsiprobe(d);
 	if(tp->fflag == 0) {
+		/* last args were 1000, now 1 */
+		dofilter(tp->work+0, C0a, C0b, 1);
+		dofilter(tp->work+1, C1a, C1b, 1);
+		dofilter(tp->work+2, C2a, C2b, 1);
+		/* */
 		dofilter(tp->rate+0, C0a, C0b, 1);
 		dofilter(tp->rate+1, C1a, C1b, 1);
 		dofilter(tp->rate+2, C2a, C2b, 1);
-		dofilter(tp->work+0, C0a, C0b, 1000);
-		dofilter(tp->work+1, C1a, C1b, 1000);
-		dofilter(tp->work+2, C2a, C2b, 1000);
 		tp->fflag = 1;
 	}
 	tp->work[0].count++;

+ 197 - 148
sys/src/fs/pc/sdata.c

@@ -1,10 +1,11 @@
 /*
- * (S)ATA(PI)/(E)IDE disk driver for file server, now with DMA!
+ * (S)ATA(PI)/(E)IDE disk driver for file server.
  * derived from /sys/src/boot/pc/sdata.c and /sys/src/9/pc/sdata.c
  *
  * we can't write message into a ctl file on the file server, so
  * enable dma and rwm as advertised by the drive & controller.
- * if that doesn't work, fix the hardware or turn it off in the source.
+ * if that doesn't work, fix the hardware or turn it off in the source
+ * (set conf.idedma = 0).
  *
  * entry points:
 ../fs64/9fsfs64.c:38: 	{ "hd", ataread,   ataseek,   atawrite,   setatapart, },
@@ -23,19 +24,25 @@
 #undef error
 
 enum {
-	DEBUGPR = 0,
 	IDEBUG = 0,
 
 	/* old stuff carried forward */
 	NCtlr=		8,
-	NDrive=		NCtlr*2,
+	NCtlrdrv=	2,		/* fixed by hardware */
+	NDrive=		NCtlr*NCtlrdrv,
 	Maxxfer=	16*1024,	/* maximum transfer size/cmd */
 
 	Read = 0,
 	Write,
+
+	/* I/O ports */
+	Ctlr0cmd =	0x1f0,
+	Ctlr0ctl =	0x3f4,
+	Ctlr1cmd =	0x170,
+	Ctlr1ctl =	0x374,
+	Ctl2cmd = Ctlr0ctl - Ctlr0cmd,
 };
 
-#define DPRINT	if(DEBUGPR)print
 #define IDPRINT if(IDEBUG)print
 
 extern SDifc sdataifc;
@@ -311,7 +318,8 @@ typedef struct Ctlr {
 	void	(*idisable)(Ctlr*);
 	SDev*	sdev;
 
-	Drive*	drive[2];
+	Drive*	drive[NCtlrdrv];
+	Target	target[NTarget];	/* contains filters for stats */
 
 	Prd*	prdt;			/* physical region descriptor table */
 	void*	prdtbase;
@@ -325,8 +333,7 @@ typedef struct Ctlr {
 	Lock;				/* register access */
 
 	/* old stuff carried forward */
-	QLock	idelock;		/* make seek & i/o atomic in ide* routines */
-	uchar	buf[RBUFSIZE];
+	QLock	idelock;	/* make seek & i/o atomic in ide* routines */
 } Ctlr;
 
 typedef struct Drive {
@@ -367,19 +374,27 @@ typedef struct Drive {
 	/* for ata* routines */
 	int	online;
 	Devsize	offset;
-	int	driveno;		/* ctlr*2 + unit */
+	int	driveno;		/* ctlr*NCtlrdrv + unit */
 
 	char	lba;		/* true if drive has logical block addressing */
 	char	multi;		/* non-0 if drive does multiple block xfers */
+
+	/*
+	 * old stuff carried forward.  it's in Drive not Ctlr to maximise
+	 * possible concurrency.
+	 */
+	uchar	buf[RBUFSIZE];
 } Drive;
 
 /* file-server-specific data */
 
 static Ctlr *atactlr[NCtlr];
-static SDev sdevs[NCtlr];
+static SDev *sdevs[NCtlr];
 
 static Drive *atadrive[NDrive];
-static SDunit sdunits[NDrive];
+// static SDunit *sdunits[NDrive];
+
+SDunit*	sdgetunit(SDev* sdev, int subno);
 
 static Drive	*atadriveprobe(int driveno);
 
@@ -632,6 +647,8 @@ atarwmmode(Drive* drive, int cmdport, int ctlport, int dev)
 	drive->rwm = rwm;
 	if (conf.idedma)
 		drive->rwmctl = drive->rwm;	/* FS special */
+	else
+		drive->rwm = 0;
 	return rwm;
 }
 
@@ -656,6 +673,8 @@ atadmamode(Drive* drive)
 	}
 	if (conf.idedma)
 		drive->dmactl = drive->dma;	/* FS special */
+	else
+		drive->dma = 0;
 	return dma;
 }
 
@@ -715,7 +734,7 @@ static void
 ataverify(Drive *dp)
 {
 	int n, nb, dev = dp->driveno;
-	uchar *buf = dp->ctlr->buf;
+	uchar *buf = dp->buf;
 
 	if (dp->ctlr == nil)
 		panic("ataverify: nil ctlr for drive");
@@ -755,10 +774,15 @@ static Drive*
 atagetdrive(int cmdport, int ctlport, int dev)
 {
 	Drive *drive;
-	int as, i, pkt;
+	int as, i, pkt, driveno;
 	uchar buf[512], *p;
 	ushort iconfig, *sp;
 
+	driveno = (cmdport == Ctlr0cmd? 0:
+		cmdport == Ctlr1cmd? NCtlrdrv: 2*NCtlrdrv);
+	if (dev == Dev1)
+		driveno++;
+
 	atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev);
 	pkt = 1;
 retry:
@@ -802,12 +826,17 @@ retry:
 	 */
 	iconfig = drive->info[Iconfig];
 	if(iconfig != 0x848A && (iconfig & 0xC000) == 0x8000){
+		print("atagetdrive: port 0x%uX dev 0x%2.2uX: packet device\n",
+			cmdport, dev);
 		if(iconfig & 0x01)
 			drive->pkt = 16;
 		else
 			drive->pkt = 12;
 	}
 	else{
+		if (iconfig == 0x848A)
+			print("atagetdrive: port 0x%uX dev 0x%2.2uX: non-packet CF device\n",
+				cmdport, dev);
 		if(drive->info[Ivalid] & 0x0001){
 			drive->c = drive->info[Iccyl];
 			drive->h = drive->info[Ichead];
@@ -835,8 +864,9 @@ retry:
 	atadmamode(drive);
 
 	if(DEBUG & DbgCONFIG){
-		print("ata: dev %2.2uX port %uX config %4.4uX capabilities %4.4uX",
-			dev, cmdport, iconfig, drive->info[Icapabilities]);
+		print("ata h%d: dev %2.2uX port %uX config %4.4uX capabilities %4.4uX",
+			driveno, dev, cmdport, iconfig,
+			drive->info[Icapabilities]);
 		print(" mwdma %4.4uX", drive->info[Imwdma]);
 		if(drive->info[Ivalid] & 0x04)
 			print(" udma %4.4uX", drive->info[Iudma]);
@@ -844,7 +874,6 @@ retry:
 		if(drive->flags&Lba48)
 			print("\tLLBA sectors %lld\n", (Wideoff)drive->sectors);
 	}
-
 	return drive;
 }
 
@@ -864,6 +893,17 @@ atasrst(int ctlport)
 	microdelay(2*1000);
 }
 
+static int drivenum = 0;	/* hope that we probe in order */
+
+static void
+updprobe(int cmdport)
+{
+	if(cmdport == Ctlr0cmd)
+		drivenum = NCtlrdrv;
+	else if (cmdport == Ctlr1cmd)
+		drivenum = 2*NCtlrdrv;
+}
+
 static SDev*
 ataprobe(int cmdport, int ctlport, int irq)
 {
@@ -871,15 +911,21 @@ ataprobe(int cmdport, int ctlport, int irq)
 	SDev *sdev;
 	Drive *drive;
 	int i, dev, error, rhi, rlo;
-	static int drivenum = 0;	/* hope that we probe in order */
+
+	if(cmdport == Ctlr0cmd)
+		drivenum = 0;
+	else if (cmdport == Ctlr1cmd)
+		drivenum = NCtlrdrv;
 
 	if(ioalloc(cmdport, 8, 0, "atacmd") < 0) {
 		print("ataprobe: Cannot allocate %X\n", cmdport);
+		updprobe(cmdport);
 		return nil;
 	}
 	if(ioalloc(ctlport+As, 1, 0, "atactl") < 0){
 		print("ataprobe: Cannot allocate %X\n", ctlport + As);
 		iofree(cmdport);
+		updprobe(cmdport);
 		return nil;
 	}
 
@@ -912,6 +958,7 @@ trydev1:
 release:
 				iofree(cmdport);
 				iofree(ctlport+As);
+				updprobe(cmdport);
 				return nil;
 			}
 			dev = Dev1;
@@ -986,8 +1033,11 @@ tryedd1:
 	}
 	memset(sdev, 0, sizeof(SDev));
 	drive->ctlr = ctlr;
-	atactlr[drivenum/2] = ctlr;
+
+	atactlr[drivenum/NCtlrdrv] = ctlr;
 	atadrive[drivenum++] = drive;
+	sdevs[drivenum/NCtlrdrv] = sdev;
+
 	if(dev == Dev0){
 		ctlr->drive[0] = drive;
 		if(!(error & 0x80)){
@@ -1015,7 +1065,7 @@ tryedd1:
 	drivenum++;
 
 	print("ata%d: cmd 0x%ux ctl 0x%ux irq %d\n",
-		(drivenum-1)/2, cmdport, ctlport, irq);
+		(drivenum-1)/NCtlrdrv, cmdport, ctlport, irq);
 	ctlr->cmdport = cmdport;
 	ctlr->ctlport = ctlport;
 	ctlr->irq = irq;
@@ -1024,13 +1074,14 @@ tryedd1:
 
 	sdev->ifc = &sdataifc;
 	sdev->ctlr = ctlr;
-	sdev->nunit = 2;
+	sdev->nunit = NCtlrdrv;
 	ctlr->sdev = sdev;
 
 	if (0)
 		for (i = drivenum - 2; i < drivenum; i++)
 			if (atadrive[i])
 				ataverify(atadrive[i]);
+	updprobe(cmdport);
 	return sdev;
 }
 
@@ -1047,15 +1098,9 @@ ataclear(SDev *sdev)
 		free(ctlr->drive[0]);
 	if (ctlr->drive[1])
 		free(ctlr->drive[1]);
+	/* TODO: clear entries in atadrive[] too */
 	if (sdev->name)
 		free(sdev->name);
-#ifdef notdef
-	/* TODO: WTF is this? */
-	if (sdev->unitflg)
-		free(sdev->unitflg);
-	if (sdev->unit)
-		free(sdev->unit);
-#endif
 	free(ctlr);
 	free(sdev);
 }
@@ -1066,7 +1111,7 @@ atastat(SDev *sdev, char *p, char *e)
 	Ctlr *ctlr = sdev->ctlr;
 
 	return seprint(p, e, "%s ata port %X ctl %X irq %d\n",
-		    	       sdev->name, ctlr->cmdport, ctlr->ctlport, ctlr->irq);
+			sdev->name, ctlr->cmdport, ctlr->ctlport, ctlr->irq);
 }
 
 #ifndef FS
@@ -1788,7 +1833,7 @@ retry:
 	else
 		status = atagenio(drive, cmdp, clen);
 	if(status == SDretry){
-		if(DbgDEBUG)
+		if(DEBUG & DbgDEBUG)
 			print("%s: retry: dma %8.8uX rwm %4.4uX\n",
 				unit->name, drive->dmactl, drive->rwmctl);
 		goto retry;
@@ -1947,13 +1992,18 @@ atapnp(void)
 	Pcidev *p;
 	int channel, ispc87415, pi, r;
 	SDev *legacy[2], *sdev, *head, *tail;
+	static int done;
+
+	if (done)
+		return nil;
+	done = 1;
 
 	legacy[0] = legacy[1] = head = tail = nil;
-	if(sdev = ataprobe(0x1F0, 0x3F4, IrqATA0)){
+	if(sdev = ataprobe(Ctlr0cmd, Ctlr0ctl, IrqATA0)){
 		head = tail = sdev;
 		legacy[0] = sdev;
 	}
-	if(sdev = ataprobe(0x170, 0x374, IrqATA1)){
+	if(sdev = ataprobe(Ctlr1cmd, Ctlr1ctl, IrqATA1)){
 		if(head != nil)
 			tail->next = sdev;
 		else
@@ -2113,52 +2163,13 @@ atapnp(void)
 			ctlr->bmiba = (p->mem[4].bar & ~0x01) + channel*8;
 		}
 	}
-
-#ifdef notdef
-if(0){
-	int port;
-	ISAConf isa;
-
-	/*
-	 * Hack for PCMCIA drives.
-	 * This will be tidied once we figure out how the whole
-	 * removeable device thing is going to work.
-	 */
-	memset(&isa, 0, sizeof(isa));
-	isa.port = 0x180;		/* change this for your machine */
-	isa.irq = 11;			/* change this for your machine */
-
-	port = isa.port+0x0C;
-	channel = pcmspecial("MK2001MPL", &isa);
-	if(channel == -1)
-		channel = pcmspecial("SunDisk", &isa);
-	if(channel == -1){
-		isa.irq = 10;
-		channel = pcmspecial("CF", &isa);
-	}
-	if(channel == -1){
-		isa.irq = 10;
-		channel = pcmspecial("OLYMPUS", &isa);
-	}
-	if(channel == -1){
-		port = isa.port+0x204;
-		channel = pcmspecial("ATA/ATAPI", &isa);
-	}
-	if(channel >= 0 && (sdev = ataprobe(isa.port, port, isa.irq)) != nil){
-		if(head != nil)
-			tail->next = sdev;
-		else
-			head = sdev;
-	}
-}
-#endif
 	return head;
 }
 
 static SDev*
 atalegacy(int port, int irq)
 {
-	return ataprobe(port, port+0x204, irq);
+	return ataprobe(port, port+Ctl2cmd, irq);
 }
 
 static SDev*
@@ -2177,16 +2188,16 @@ ataid(SDev* sdev)
 	if(sdev == nil)
 		return nil;
 	ctlr = sdev->ctlr;
-	if(ctlr->cmdport == 0x1F0 || ctlr->cmdport == 0x170)
+	if(ctlr->cmdport == Ctlr0cmd || ctlr->cmdport == Ctlr1cmd)
 		i = 2;
 	else
 		i = 0;
 	while(sdev){
 		if(sdev->ifc == &sdataifc){
 			ctlr = sdev->ctlr;
-			if(ctlr->cmdport == 0x1F0)
+			if(ctlr->cmdport == Ctlr0cmd)
 				sdev->idno = 'C';
-			else if(ctlr->cmdport == 0x170)
+			else if(ctlr->cmdport == Ctlr1cmd)
 				sdev->idno = 'D';
 			else{
 				sdev->idno = 'C'+i;
@@ -2418,13 +2429,37 @@ atadriveprobe(int driveno)
 	return atapart(drive);
 }
 
+static void
+cmd_stat(int, char*[])
+{
+	Ctlr *ctlr;
+	int ctlrno, targetno;
+	Target *tp;
+
+	for(ctlrno = 0; ctlrno < nelem(atactlr); ctlrno++){
+		ctlr = atactlr[ctlrno];
+		if(ctlr == nil || ctlr->sdev == nil)
+			continue;
+		for(targetno = 0; targetno < NTarget; targetno++){
+			tp = &ctlr->target[targetno];
+			if(tp->fflag == 0)
+				continue;
+			print("\t%d.%d work =%7W%7W%7W xfrs\n",
+				ctlrno, targetno,
+				tp->work+0, tp->work+1, tp->work+2);
+			print("\t    rate =%7W%7W%7W tBps\n",
+				tp->rate+0, tp->rate+1, tp->rate+2);
+		}
+	}
+}
+
 /* find all the controllers, enable interrupts, set up SDevs & SDunits */
 int
 atainit(void)
 {
 	unsigned i;
 	SDev *sdp;
-	SDunit *sup;
+	SDev **sdpp;
 	static int first = 1;
 
 	if (first)
@@ -2434,22 +2469,20 @@ atainit(void)
 
 	atapnp();
 
-	for (sdp = sdevs; sdp < sdevs + NCtlr; sdp++) {
-		i = sdp - sdevs;
+	for (sdpp = sdevs; sdpp < sdevs + nelem(sdevs); sdpp++) {
+		sdp = *sdpp;
+		if (sdp == nil)
+			continue;
+		i = sdpp - sdevs;
 		sdp->ifc = &sdataifc;
-		sdp->nunit = 2;
+		sdp->nunit = NCtlrdrv;
 		sdp->index = i;
 		sdp->idno = 'C' + i;
 		sdp->ctlr = atactlr[i];
 		if (sdp->ctlr != nil)
 			ataenable(sdp);
 	}
-	for (sup = sdunits; sup < sdunits + NDrive; sup++) {
-		i = sup - sdunits;
-		sup->dev = sdevs + i/2;	/* controller */
-		sup->subno = i%2;	/* drive within controller */
-		snprint(sup->name, sizeof sup->name, "h%d", i);
-	}
+	cmd_install("stati", "-- ide/ata stats", cmd_stat);
 	return 0xFF;
 }
 
@@ -2474,37 +2507,75 @@ setatapart(int driveno, char *)
 	return 1;
 }
 
-/*
- * connect the old nvram (ata* routines) and ide* routines to sdata.c.
- * an ugly hack.
- */
+static void
+keepstats(Drive *dp, int dbytes)
+{
+	Target *tp = &dp->ctlr->target[dp->driveno%NCtlrdrv];
+
+	qlock(tp);
+//	if(tp->ok == 0)
+//		scsiprobe(d);
+	if(tp->fflag == 0) {
+		dofilter(tp->work+0, C0a, C0b, 1);	/* was , 1000); */
+		dofilter(tp->work+1, C1a, C1b, 1);	/* was , 1000); */
+		dofilter(tp->work+2, C2a, C2b, 1);	/* was , 1000); */
+		dofilter(tp->rate+0, C0a, C0b, 1);
+		dofilter(tp->rate+1, C1a, C1b, 1);
+		dofilter(tp->rate+2, C2a, C2b, 1);
+		tp->fflag = 1;
+	}
+	tp->work[0].count++;
+	tp->work[1].count++;
+	tp->work[2].count++;
+	tp->rate[0].count += dbytes;
+	tp->rate[1].count += dbytes;
+	tp->rate[2].count += dbytes;
+	qunlock(tp);
+}
+
 static long
-ataxfer(Drive *dp, void *, int inout, Devsize start, long bytes)
+ataxfer(Drive *dp, int inout, Devsize start, long bytes)
 {
 	unsigned driveno = dp->driveno;
 	ulong secsize = dp->secsize, sects;
-	SDunit *sdp = sdunits + driveno;
+	SDunit *unit = sdgetunit(sdevs[driveno/NCtlrdrv], driveno%NCtlrdrv);
 
+	if (unit == nil) {
+		print("mvsataxfer: nil unit\n");
+		return -1;
+	}
 	if (dp->driveno == -1)
 		panic("ataxfer: dp->driveno unset");
-	if (sdp->dev != sdevs + driveno/2)
-		panic("ataxfer: SDunit[%d].dev is wrong controller", driveno);
-	if (sdp->subno != driveno%2)
-		panic("ataxfer: SDunit[%d].subno is %d, not %d", driveno, sdp->subno, driveno%2);
-	if (sdp->sectors == 0) {
-		sdp->sectors = dp->sectors;
-		sdp->secsize = secsize;
+	/*
+	 * unit->dev will be nil if the controller is missing (e.g., h0 on a
+	 * machine with only sdD, not sdC), so make this a non-fatal error.
+	 */
+	if (unit->dev == nil) {
+		print("ataxfer: missing controller for h%d\n", driveno);
+		return -1;
+	}
+	if (unit->dev != sdevs[driveno/NCtlrdrv])
+		panic("ataxfer: sdunits[%d].dev=%p is wrong controller (want %p)",
+			driveno, unit->dev, sdevs + driveno/NCtlrdrv);
+	if (unit->subno != driveno%NCtlrdrv)
+		panic("ataxfer: sdunits[%d].subno is %d, not %d",
+			driveno, unit->subno, driveno%NCtlrdrv);
+	keepstats(dp, bytes);
+	if (unit->sectors == 0) {
+		unit->sectors = dp->sectors;
+		unit->secsize = secsize;
 	}
 	sects = (bytes + secsize - 1) / secsize;	/* round up */
 	if (start%secsize != 0)
 		print("ataxfer: start offset not on sector boundary\n");
-	return scsibio(sdp, 0, inout, dp->ctlr->buf, sects, start/secsize);
+	return scsibio(unit, 0, inout, dp->buf, sects, start/secsize);
 }
 
-/* ataread & atawrite do the real work; ideread and idewrite just call them */
-
-/* paranoia: only permit one outstanding I/O operation at a time */
-static QLock iolock;
+/*
+ * ataread & atawrite do the real work; ideread & idewrite just call them.
+ * ataread & atawrite are called by the nvram routines.
+ * ideread & idewrite are called for normal file server I/O.
+ */
 
 Off
 ataread(int driveno, void *a, long n)
@@ -2512,35 +2583,30 @@ ataread(int driveno, void *a, long n)
 	int skip;
 	Off rv, i;
 	uchar *aa = a;
-	Ctlr *cp;
+//	Ctlr *cp;
 	Drive *dp;
 
 	dp = atadrive[driveno];
 	if(dp == nil || !dp->online)
 		return 0;
 
-	iolock.name = "ataio";
-	qlock(&iolock);
-	cp = dp->ctlr;
+//	cp = dp->ctlr;
 	if (dp->secsize == 0)
 		panic("ataread: sector size of zero");
 	skip = dp->offset % dp->secsize;
 	for(rv = 0; rv < n; rv += i){
-		i = ataxfer(dp, nil, Read, dp->offset+rv-skip, n-rv+skip);
+		i = ataxfer(dp, Read, dp->offset+rv-skip, n-rv+skip);
 		if(i == 0)
 			break;
-		if(i < 0) {
-			qunlock(&iolock);
+		if(i < 0)
 			return -1;
-		}
 		i -= skip;
 		if(i > n - rv)
 			i = n - rv;
-		memmove(aa+rv, cp->buf + skip, i);
+		memmove(aa+rv, dp->buf + skip, i);
 		skip = 0;
 	}
 	dp->offset += rv;
-	qunlock(&iolock);
 	return rv;
 }
 
@@ -2549,15 +2615,14 @@ atawrite(int driveno, void *a, long n)
 {
 	Off rv, i, partial;
 	uchar *aa = a;
-	Ctlr *cp;
+//	Ctlr *cp;
 	Drive *dp;
 
 	dp = atadrive[driveno];
 	if(dp == nil || !dp->online)
 		return 0;
 
-	qlock(&iolock);
-	cp = dp->ctlr;
+//	cp = dp->ctlr;
 
 	/*
 	 *  if not starting on a sector boundary,
@@ -2567,19 +2632,15 @@ atawrite(int driveno, void *a, long n)
 		panic("atawrite: sector size of zero");
 	partial = dp->offset % dp->secsize;
 	if(partial){
-		if (ataxfer(dp, nil, Read, dp->offset-partial, dp->secsize) < 0){
-			qunlock(&iolock);
+		if (ataxfer(dp, Read, dp->offset-partial, dp->secsize) < 0)
 			return -1;
-		}
 		if(partial+n > dp->secsize)
 			rv = dp->secsize - partial;
 		else
 			rv = n;
-		memmove(cp->buf+partial, aa, rv);
-		if(ataxfer(dp, nil, Write, dp->offset-partial, dp->secsize) < 0){
-			qunlock(&iolock);
+		memmove(dp->buf+partial, aa, rv);
+		if(ataxfer(dp, Write, dp->offset-partial, dp->secsize) < 0)
 			return -1;
-		}
 	} else
 		rv = 0;
 
@@ -2592,14 +2653,12 @@ atawrite(int driveno, void *a, long n)
 		i = n - rv;
 		if(i > Maxxfer)
 			i = Maxxfer;
-		memmove(cp->buf, aa+rv, i);
-		i = ataxfer(dp, nil, Write, dp->offset+rv, i);
+		memmove(dp->buf, aa+rv, i);
+		i = ataxfer(dp, Write, dp->offset+rv, i);
 		if(i == 0)
 			break;
-		if(i < 0) {
-			qunlock(&iolock);
+		if(i < 0)
 			return -1;
-		}
 	}
 
 	/*
@@ -2607,24 +2666,19 @@ atawrite(int driveno, void *a, long n)
 	 *  read in the last sector before writing it out.
 	 */
 	if(partial){
-		if(ataxfer(dp, nil, Read, dp->offset+rv, dp->secsize) < 0) {
-			qunlock(&iolock);
+		if(ataxfer(dp, Read, dp->offset+rv, dp->secsize) < 0)
 			return -1;
-		}
-		memmove(cp->buf, aa+rv, partial);
-		if(ataxfer(dp, nil, Write, dp->offset+rv, dp->secsize) < 0) {
-			qunlock(&iolock);
+		memmove(dp->buf, aa+rv, partial);
+		if(ataxfer(dp, Write, dp->offset+rv, dp->secsize) < 0)
 			return -1;
-		}
 		rv += partial;
 	}
 	dp->offset += rv;
-	qunlock(&iolock);
 	return rv;
 }
 
 /*
- * normal interface
+ * normal I/O interface
  */
 
 /* result is size of d in blocks of RBUFSIZE bytes */
@@ -2652,7 +2706,7 @@ ideinit(Device *d)
 	if (d->private)
 		return;
 	/* call setatapart() first in case we didn't boot off this drive */
-	driveno = d->wren.ctrl*2 + d->wren.targ;
+	driveno = d->wren.ctrl*NCtlrdrv + d->wren.targ;
 	setatapart(driveno, "disk");
 	dp = atadriveprobe(driveno);
 	if (dp) {
@@ -2669,11 +2723,6 @@ ideinit(Device *d)
 	}
 }
 
-/*
- * can't qlock(cp) here because atagenio() does so, & would deadlock,
- * so we introduce a second lock (idelock).
- */
-
 int
 ideread(Device *d, Devsize b, void *c)
 {
@@ -2688,13 +2737,13 @@ ideread(Device *d, Devsize b, void *c)
 	if (cp == nil)
 		panic("ideread: no controller for drive");
 
-	cp->idelock.name = "ideio";
 	qlock(&cp->idelock);
+	cp->idelock.name = "ideio";
 	driveno = dp->driveno;
 	if (driveno == -1)
 		panic("ideread: dp->driveno unset");
-	IDPRINT("ideread(dev %lux, %lld, %lux, %d): %lux\n",
-		(ulong)d, (Wideoff)b, (ulong)c, driveno, (ulong)dp);
+	IDPRINT("ideread(dev %p, %lld, %p, %d): %p\n", d, (Wideoff)b, c,
+		driveno, dp);
 	ataseek(driveno, b * RBUFSIZE);
 	x = ataread(driveno, c, RBUFSIZE) != RBUFSIZE;
 	qunlock(&cp->idelock);
@@ -2715,13 +2764,13 @@ idewrite(Device *d, Devsize b, void *c)
 	if (cp == nil)
 		panic("idewrite: no controller for drive");
 
-	cp->idelock.name = "ideio";
 	qlock(&cp->idelock);
+	cp->idelock.name = "ideio";
 	driveno = dp->driveno;
 	if (driveno == -1)
 		panic("idewrite: dp->driveno unset");
-	IDPRINT("idewrite(%ux, %lld, %ux): driveno %d\n",
-		(int)d, (Wideoff)b, (int)c, driveno);
+	IDPRINT("idewrite(%p, %lld, %p): driveno %d\n", d, (Wideoff)b, c,
+		driveno);
 	ataseek(driveno, b * RBUFSIZE);
 	x = atawrite(driveno, c, RBUFSIZE) != RBUFSIZE;
 	qunlock(&cp->idelock);

+ 7 - 3
sys/src/fs/port/config.c

@@ -79,6 +79,7 @@ devcmpr(Device *d1, Device *d2)
 		case Devworm:
 		case Devlworm:
 		case Devide:
+		case Devmarvsata:
 			if(d1->wren.ctrl == d2->wren.ctrl)
 			if(d1->wren.targ == d2->wren.targ)
 			if(d1->wren.lun == d2->wren.lun)
@@ -225,12 +226,15 @@ config(void)
 		d->type = Devnone;
 		break;
 
-	case 'w':	/* w[#.]#[.#] wren [ctrl] unit [lun] */
-	case 'h':	/* h[#.]# ide [ctlr] unit */
+	case 'w':	/* w[#.]#[.#] wren	[ctrl] unit [lun] */
+	case 'h':	/* h[#.]# ide		[ctlr] unit */
+	case 'm':	/* m[#.]# marvell sata	[ctlr] unit */
 	case 'r':	/* r# worm side */
 	case 'l':	/* l# labelled-worm side */
 		icp = f.charp;
-		if(c == 'h')
+		if(c == 'm')
+			d->type = Devmarvsata;
+		else if(c == 'h')
 			d->type = Devide;
 		else
 			d->type = Devwren;

+ 194 - 6
sys/src/fs/port/devsd.c

@@ -12,10 +12,11 @@
 
 #define parttrace 0
 
-extern SDifc sdataifc;
+extern SDifc sdataifc; // , sdmv50xxifc;
 
 SDifc* sdifc[] = {
 	&sdataifc,
+//	&sdmv50xxifc,
 	nil,
 };
 
@@ -149,7 +150,7 @@ sdinitpart(SDunit* unit)
 	return 1;
 }
 
-static SDunit*
+SDunit*
 sdgetunit(SDev* sdev, int subno)
 {
 	int index;
@@ -191,7 +192,6 @@ sdgetunit(SDev* sdev, int subno)
 		sdunit[index] = unit;
 	}
 	qunlock(&sdqlock);
-
 	return unit;
 }
 
@@ -206,11 +206,9 @@ sdindex2unit(int index)
 	 * The device will be probed if it has not already been
 	 * successfully accessed.
 	 */
-	for(sdev = sdlist; sdev != nil; sdev = sdev->next){
+	for(sdev = sdlist; sdev != nil; sdev = sdev->next)
 		if(index >= sdev->index && index < sdev->index+sdev->nunit)
 			return sdgetunit(sdev, index-sdev->index);
-	}
-
 	return nil;
 }
 
@@ -597,3 +595,193 @@ sdmalloc(void *p, ulong sz)
 	}
 	return malloc(sz);
 }
+
+/*
+ * SCSI simulation for non-SCSI devices
+ */
+int
+sdsetsense(SDreq *r, int status, int key, int asc, int ascq)
+{
+	int len;
+	SDunit *unit;
+	
+	unit = r->unit;
+	unit->sense[2] = key;
+	unit->sense[12] = asc;
+	unit->sense[13] = ascq;
+
+	if(status == SDcheck && !(r->flags & SDnosense)){
+		/* request sense case from sdfakescsi */
+		len = sizeof unit->sense;
+		if(len > sizeof r->sense-1)
+			len = sizeof r->sense-1;
+		memmove(r->sense, unit->sense, len);
+		unit->sense[2] = 0;
+		unit->sense[12] = 0;
+		unit->sense[13] = 0;
+		r->flags |= SDvalidsense;
+		return SDok;
+	}
+	return status;
+}
+
+int
+sdfakescsi(SDreq *r, void *info, int ilen)
+{
+	uchar *cmd, *p;
+	uvlong len;
+	SDunit *unit;
+	
+	cmd = r->cmd;
+	r->rlen = 0;
+	unit = r->unit;
+	
+	/*
+	 * Rewrite read(6)/write(6) into read(10)/write(10).
+	 */
+	switch(cmd[0]){
+	case 0x08:	/* read */
+	case 0x0A:	/* write */
+		cmd[9] = 0;
+		cmd[8] = cmd[4];
+		cmd[7] = 0;
+		cmd[6] = 0;
+		cmd[5] = cmd[3];
+		cmd[4] = cmd[2];
+		cmd[3] = cmd[1] & 0x0F;
+		cmd[2] = 0;
+		cmd[1] &= 0xE0;
+		cmd[0] |= 0x20;
+		break;
+	}
+
+	/*
+	 * Map SCSI commands into ATA commands for discs.
+	 * Fail any command with a LUN except INQUIRY which
+	 * will return 'logical unit not supported'.
+	 */
+	if((cmd[1]>>5) && cmd[0] != 0x12)
+		return sdsetsense(r, SDcheck, 0x05, 0x25, 0);
+	
+	switch(cmd[0]){
+	default:
+		return sdsetsense(r, SDcheck, 0x05, 0x20, 0);
+	
+	case 0x00:	/* test unit ready */
+		return sdsetsense(r, SDok, 0, 0, 0);
+	
+	case 0x03:	/* request sense */
+		if(cmd[4] < sizeof unit->sense)
+			len = cmd[4];
+		else
+			len = sizeof unit->sense;
+		if(r->data && r->dlen >= len){
+			memmove(r->data, unit->sense, len);
+			r->rlen = len;
+		}
+		return sdsetsense(r, SDok, 0, 0, 0);
+	
+	case 0x12:	/* inquiry */
+		/* warning: useless or misleading comparison: UCHAR < 0x100 */
+		if(cmd[4] < sizeof unit->inquiry)
+			len = cmd[4];
+		else
+			len = sizeof unit->inquiry;
+		if(r->data && r->dlen >= len){
+			memmove(r->data, r->sense, len);
+			r->rlen = len;
+		}
+		return sdsetsense(r, SDok, 0, 0, 0);
+
+	case 0x1B:	/* start/stop unit */
+		/*
+		 * nop for now, can use power management later.
+		 */
+		return sdsetsense(r, SDok, 0, 0, 0);
+	
+	case 0x25:	/* read capacity */
+		if((cmd[1] & 0x01) || cmd[2] || cmd[3])
+			return sdsetsense(r, SDcheck, 0x05, 0x24, 0);
+		if(r->data == nil || r->dlen < 8)
+			return sdsetsense(r, SDcheck, 0x05, 0x20, 1);
+		
+		/*
+		 * Read capacity returns the LBA of the last sector.
+		 */
+		len = unit->sectors - 1;
+		p = r->data;
+		*p++ = len>>24;
+		*p++ = len>>16;
+		*p++ = len>>8;
+		*p++ = len;
+		len = 512;
+		*p++ = len>>24;
+		*p++ = len>>16;
+		*p++ = len>>8;
+		*p++ = len;
+		r->rlen = p - (uchar*)r->data;
+		return sdsetsense(r, SDok, 0, 0, 0);
+
+	case 0x9E:	/* long read capacity */
+		if((cmd[1] & 0x01) || cmd[2] || cmd[3])
+			return sdsetsense(r, SDcheck, 0x05, 0x24, 0);
+		if(r->data == nil || r->dlen < 8)
+			return sdsetsense(r, SDcheck, 0x05, 0x20, 1);	
+		/*
+		 * Read capcity returns the LBA of the last sector.
+		 */
+		len = unit->sectors - 1;
+		p = r->data;
+		*p++ = len>>56;
+		*p++ = len>>48;
+		*p++ = len>>40;
+		*p++ = len>>32;
+		*p++ = len>>24;
+		*p++ = len>>16;
+		*p++ = len>>8;
+		*p++ = len;
+		len = 512;
+		*p++ = len>>24;
+		*p++ = len>>16;
+		*p++ = len>>8;
+		*p++ = len;
+		r->rlen = p - (uchar*)r->data;
+		return sdsetsense(r, SDok, 0, 0, 0);
+	
+	case 0x5A:	/* mode sense */
+		return sdmodesense(r, cmd, info, ilen);
+	
+	case 0x28:	/* read */
+	case 0x2A:	/* write */
+		return SDnostatus;
+	}
+}
+
+int
+sdmodesense(SDreq *r, uchar *cmd, void *info, int ilen)
+{
+	int len;
+	uchar *data;
+	
+	/*
+	 * Fake a vendor-specific request with page code 0,
+	 * return the drive info.
+	 */
+	if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
+		return sdsetsense(r, SDcheck, 0x05, 0x24, 0);
+	len = (cmd[7]<<8)|cmd[8];
+	if(len == 0)
+		return SDok;
+	if(len < 8+ilen)
+		return sdsetsense(r, SDcheck, 0x05, 0x1A, 0);
+	if(r->data == nil || r->dlen < len)
+		return sdsetsense(r, SDcheck, 0x05, 0x20, 1);
+	data = r->data;
+	memset(data, 0, 8);
+	data[0] = ilen>>8;
+	data[1] = ilen;
+	if(ilen)
+		memmove(data+8, info, ilen);
+	r->rlen = 8+ilen;
+	return sdsetsense(r, SDok, 0, 0, 0);
+}

+ 20 - 9
sys/src/fs/port/main.c

@@ -5,6 +5,8 @@
 
 #include	"9p1.h"
 
+Rendez dawnrend;
+
 void
 machinit(void)
 {
@@ -131,6 +133,12 @@ main(void)
 		printinit();
 		procinit();
 		clockinit();
+
+		print("\nPlan 9 %d-bit file server with %d-deep indir blks%s\n",
+			sizeof(Off)*8 - 1, NIBLOCK,
+			(conf.idedma? " and IDE DMA+RWM": ""));
+		printsizes();
+
 		alarminit();
 
 		mainlock.wr.name = "mainr";
@@ -159,12 +167,7 @@ main(void)
 		gidspace = ialloc(conf.gidspace * sizeof(*gidspace), 0);
 		authinit();
 
-		print("Plan 9 %d-bit file server with %d-deep indir blks%s\n",
-			sizeof(Off)*8 - 1, NIBLOCK,
-			(conf.idedma? " and IDE DMA+RWM": ""));
-		printsizes();
-
-		print("iobufinit:");
+		print("iobufinit\n");
 		iobufinit();
 
 		arginit();
@@ -172,6 +175,7 @@ main(void)
 		userinit(touser, 0, "ini");
 
 	predawn = 0;
+		wakeup(&dawnrend);
 		launchinit();
 		schedinit();
 }
@@ -312,13 +316,20 @@ exit(void)
 	while(active.machs)
 		delay(1);
 
-	print("halted.  press a key to reboot sooner than %d mins.\n",
-		Keydelay/60);
-	delay(300);		/* time to drain print q */
+	print("halted at %T.\npress a key to reboot sooner than %d mins.\n",
+		time(), Keydelay/60);
+	delay(500);		/* time to drain print q */
 
 	splhi();
 	/* reboot after delay (for debugging) or at key press */
 	rawchar(Keydelay);
+
+	spllo();
+	delay(500);		/* time to drain echo q */
+	print("rebooting...\n");
+	delay(500);		/* time to drain print q */
+
+	splhi();
 	consreset();
 	firmware();
 }

+ 2 - 0
sys/src/fs/port/portdat.h

@@ -913,6 +913,7 @@ enum
 	Devide,			/* IDE drive */
 	Devswab,		/* swab data between mem and device */
 	Devmirr,		/* mirror devices */
+	Devmarvsata,		/* Marvell sata disk drive */
 	MAXDEV
 };
 
@@ -986,3 +987,4 @@ Cons	cons;
 #pragma	varargck	type	"G"	int
 
 extern int (*fsprotocol[])(Msgbuf*);
+extern Rendez dawnrend;

+ 10 - 6
sys/src/fs/port/sd.h

@@ -21,6 +21,7 @@ typedef struct SDunit {
 	SDev*	dev;
 	int	subno;
 	uchar	inquiry[256];		/* format follows SCSI spec */
+	uchar	sense[18];		/* format follows SCSI spec */
 	char	name[NAMELEN];
 	Rendez	rendez;
 
@@ -105,12 +106,15 @@ enum {
 };
 
 /* sdscsi.c */
-extern int scsiverify(SDunit*);
-extern int scsionline(SDunit*);
-extern long scsibio(SDunit*, int, int, void*, long, Off);
-extern SDev* scsiid(SDev*, SDifc*);
-
-extern long sdbio(SDunit *unit, SDpart *pp, void *a, long len, Off off);
+int	scsiverify(SDunit*);
+int	scsionline(SDunit*);
+long	scsibio(SDunit*, int, int, void*, long, Off);
+SDev*	scsiid(SDev*, SDifc*);
+
+/* devsd.c */
+int	sdfakescsi(SDreq *r, void *info, int ilen);
+int	sdmodesense(SDreq *r, uchar *cmd, void *info, int ilen);
+long	sdbio(SDunit *unit, SDpart *pp, void *a, long len, Off off);
 void	partition(SDunit*);
 void	addpartconf(SDunit*);
 SDpart* sdfindpart(SDunit*, char*);

+ 5 - 1
sys/src/fs/port/sub.c

@@ -609,6 +609,9 @@ Zfmt(Fmt* fmt)
 	case Devide:
 		c = 'h';
 		goto d1;
+	case Devmarvsata:
+		c = 'm';
+		goto d1;
 	case Devworm:
 		c = 'r';
 		goto d1;
@@ -675,7 +678,7 @@ Wfmt(Fmt* fmt)
 	char s[30];
 
 	a = va_arg(fmt->args, Filter*);
-	sprint(s, "%lud", fdf(a->filter, a->c3*a->c1));
+	snprint(s, sizeof s, "%lud", fdf(a->filter, a->c3*a->c1));
 
 	return fmtstrcpy(fmt, s);
 }
@@ -1337,6 +1340,7 @@ loop:
 	case Devlworm:
 	case Devwren:
 	case Devide:
+	case Devmarvsata:
 		break;
 
 	case Devswab: