Browse Source

Plan 9 from Bell Labs 2007-05-11

David du Colombier 17 years ago
parent
commit
9d632453e6

+ 19 - 14
dist/replica/_plan9.db

@@ -305,7 +305,7 @@
 386/bin/ip/ipconfig - 775 sys sys 1178654264 156933
 386/bin/ip/linklocal - 775 sys sys 1177530964 42790
 386/bin/ip/ping - 775 sys sys 1178568288 83220
-386/bin/ip/ppp - 775 sys sys 1178568289 218961
+386/bin/ip/ppp - 775 sys sys 1178826954 218964
 386/bin/ip/pppoe - 775 sys sys 1168402326 77787
 386/bin/ip/pptp - 775 sys sys 1169612026 127215
 386/bin/ip/pptpd - 775 sys sys 1178568289 124670
@@ -561,19 +561,19 @@
 386/lib/libgeometry.a - 664 sys sys 1168402366 50470
 386/lib/libhtml.a - 664 sys sys 1176432132 229152
 386/lib/libhttpd.a - 664 sys sys 1177283321 99734
-386/lib/libip.a - 664 sys sys 1178654265 34710
+386/lib/libip.a - 664 sys sys 1178826954 34710
 386/lib/libl.a - 664 sys sys 1168402367 5372
 386/lib/libmach.a - 664 sys sys 1173410637 785440
 386/lib/libmemdraw.a - 664 sys sys 1168402369 284092
 386/lib/libmemlayer.a - 664 sys sys 1168402369 47360
 386/lib/libmp.a - 664 sys sys 1176520528 79978
-386/lib/libndb.a - 664 sys sys 1176520529 64470
+386/lib/libndb.a - 664 sys sys 1178826955 64470
 386/lib/libplumb.a - 664 sys sys 1168402370 19408
 386/lib/libregexp.a - 664 sys sys 1168402370 37438
 386/lib/libscribble.a - 664 sys sys 1175972562 107238
 386/lib/libsec.a - 664 sys sys 1176520530 646724
 386/lib/libstdio.a - 664 sys sys 1176432133 126062
-386/lib/libsunrpc.a - 664 sys sys 1178508502 353148
+386/lib/libsunrpc.a - 664 sys sys 1178826956 353148
 386/lib/libthread.a - 664 sys sys 1176432134 71932
 386/lib/libventi.a - 664 sys sys 1168402374 97858
 386/mbr - 775 sys sys 1131317338 407
@@ -6068,7 +6068,7 @@ sys/include/frame.h - 664 sys sys 1147706379 2682
 sys/include/geometry.h - 664 sys sys 1014929063 2632
 sys/include/html.h - 664 sys sys 1128662123 15232
 sys/include/httpd.h - 664 sys sys 1177187803 5794
-sys/include/ip.h - 664 sys sys 1176499323 2978
+sys/include/ip.h - 664 sys sys 1178768502 2597
 sys/include/keyboard.h - 664 sys sys 1131637696 865
 sys/include/libc.h - 664 sys sys 1168306860 19851
 sys/include/libsec.h - 664 sys sys 1124709121 9345
@@ -7630,7 +7630,7 @@ sys/man/3/ether - 664 sys sys 1178597986 2890
 sys/man/3/floppy - 664 sys sys 954378905 881
 sys/man/3/fs - 664 sys sys 1175145095 3147
 sys/man/3/i82365 - 664 sys sys 954378906 884
-sys/man/3/ip - 664 sys sys 1178575371 25066
+sys/man/3/ip - 664 sys sys 1178768702 24744
 sys/man/3/kbmap - 664 sys sys 1131110122 1732
 sys/man/3/kprof - 664 sys sys 1018029972 1377
 sys/man/3/loopback - 664 sys sys 964662153 1995
@@ -7972,7 +7972,7 @@ sys/src/9/ip/ptclbsum.c - 664 sys sys 1022588099 1243
 sys/src/9/ip/rudp.c - 664 sys sys 1055700790 21415
 sys/src/9/ip/tcp.c - 664 sys sys 1170031827 65877
 sys/src/9/ip/tripmedium.c - 664 sys sys 1045063515 7136
-sys/src/9/ip/udp.c - 664 sys sys 1178057621 13132
+sys/src/9/ip/udp.c - 664 sys sys 1178817924 13317
 sys/src/9/mkfile - 664 sys sys 1063857477 205
 sys/src/9/mtx - 20000000775 sys sys 1123676466 0
 sys/src/9/mtx/clock.c - 664 sys sys 1032053278 1293
@@ -8003,6 +8003,7 @@ sys/src/9/mtx/trap.c - 664 sys sys 1105030157 15882
 sys/src/9/mtx/uarti8250.c - 664 sys sys 1018721288 11590
 sys/src/9/pc - 20000000775 sys sys 1161233143 0
 sys/src/9/pc/a100p.cp - 444 sys sys 1159735144 21984
+sys/src/9/pc/ahci.h - 664 sys sys 1178833481 6297
 sys/src/9/pc/apbootstrap.s - 664 sys sys 1131293655 3037
 sys/src/9/pc/apic.c - 664 sys sys 1174415344 8991
 sys/src/9/pc/apm.c - 664 sys sys 1131290210 3723
@@ -8013,7 +8014,7 @@ sys/src/9/pc/bios32.c - 664 sys sys 1173287378 3029
 sys/src/9/pc/cga.c - 664 sys sys 1015014513 1843
 sys/src/9/pc/dat.h - 664 sys sys 1173289271 6917
 sys/src/9/pc/devarch.c - 664 sys sys 1168315311 19342
-sys/src/9/pc/devether.c - 664 sys sys 1178548254 10316
+sys/src/9/pc/devether.c - 664 sys sys 1178823613 10489
 sys/src/9/pc/devfloppy.c - 664 sys sys 1142958305 20139
 sys/src/9/pc/devi82365.c - 664 sys sys 1146318335 20504
 sys/src/9/pc/devlm78.c - 664 sys sys 1128255048 6291
@@ -8098,6 +8099,7 @@ sys/src/9/pc/screen.c - 664 sys sys 1136336092 13971
 sys/src/9/pc/screen.h - 664 sys sys 1147023549 4256
 sys/src/9/pc/sd53c8xx.c - 664 sys sys 1170456695 55276
 sys/src/9/pc/sd53c8xx.n - 664 sys sys 1131290556 12657
+sys/src/9/pc/sd63xxesb.c - 664 sys sys 1178836359 35774
 sys/src/9/pc/sdata.c - 664 sys sys 1175564140 52809
 sys/src/9/pc/sdmv50xx.c - 664 sys sys 1177393607 33810
 sys/src/9/pc/sdmylex.c - 664 sys sys 1171321627 28237
@@ -8196,14 +8198,14 @@ sys/src/9/port/mkrootall - 775 sys sys 1055954696 386
 sys/src/9/port/mkrootc - 775 sys sys 1055954695 717
 sys/src/9/port/mksystab - 664 sys sys 1014931176 783
 sys/src/9/port/mul64fract.c - 664 sys sys 1071671674 867
-sys/src/9/port/netif.c - 664 sys sys 1170456606 13474
+sys/src/9/port/netif.c - 664 sys sys 1178831077 13474
 sys/src/9/port/netif.h - 664 sys sys 1066514947 2975
 sys/src/9/port/page.c - 664 sys sys 1131636090 11128
 sys/src/9/port/parse.c - 664 sys sys 1014931177 2026
 sys/src/9/port/pgrp.c - 664 sys sys 1138458260 4760
 sys/src/9/port/portclock.c - 664 sys sys 1146746630 4276
 sys/src/9/port/portdat.h - 664 sys sys 1155995676 22703
-sys/src/9/port/portfns.h - 664 sys sys 1146746630 11059
+sys/src/9/port/portfns.h - 664 sys sys 1178831066 11059
 sys/src/9/port/portmkfile - 664 sys sys 1173788325 2069
 sys/src/9/port/print.c - 664 sys sys 1014931178 227
 sys/src/9/port/proc.c - 664 sys sys 1176658321 28742
@@ -9554,7 +9556,7 @@ sys/src/cmd/auth/factotum/rpc.c - 664 sys sys 1107633794 11167
 sys/src/cmd/auth/factotum/rsa.c - 664 sys sys 1107706104 3416
 sys/src/cmd/auth/factotum/secstore.c - 664 sys sys 1140272941 14955
 sys/src/cmd/auth/factotum/sshrsa.c - 664 sys sys 1107633793 3416
-sys/src/cmd/auth/factotum/util.c - 664 sys sys 1143694878 18460
+sys/src/cmd/auth/factotum/util.c - 664 sys sys 1178832638 18451
 sys/src/cmd/auth/factotum/wep.c - 664 sys sys 1107706104 2140
 sys/src/cmd/auth/guard.srv.c - 664 sys sys 1172776773 2873
 sys/src/cmd/auth/iam.c - 664 sys sys 1015008430 841
@@ -12533,7 +12535,7 @@ sys/src/cmd/ip/ppp/dotest - 775 sys sys 944961006 152
 sys/src/cmd/ip/ppp/ipaux.c - 664 sys sys 1125529107 2328
 sys/src/cmd/ip/ppp/mkfile - 664 sys sys 1063897576 352
 sys/src/cmd/ip/ppp/mppc.c - 664 sys sys 1015090267 16624
-sys/src/cmd/ip/ppp/ppp.c - 664 sys sys 1143759338 59898
+sys/src/cmd/ip/ppp/ppp.c - 664 sys sys 1178810697 59924
 sys/src/cmd/ip/ppp/ppp.h - 664 sys sys 1091904423 8284
 sys/src/cmd/ip/ppp/testppp.c - 664 sys sys 1045505281 3011
 sys/src/cmd/ip/ppp/thw.c - 664 sys sys 1015090268 5962
@@ -13593,7 +13595,7 @@ sys/src/cmd/troff/n4.c - 664 sys sys 984718893 12310
 sys/src/cmd/troff/n5.c - 664 sys sys 944961293 14261
 sys/src/cmd/troff/n6.c - 664 sys sys 944961294 4862
 sys/src/cmd/troff/n7.c - 664 sys sys 944961294 12476
-sys/src/cmd/troff/n8.c - 664 sys sys 944961294 10197
+sys/src/cmd/troff/n8.c - 664 sys sys 1178823422 10250
 sys/src/cmd/troff/n9.c - 664 sys sys 944961294 9076
 sys/src/cmd/troff/ni.c - 664 sys sys 944961294 8492
 sys/src/cmd/troff/suftab.c - 664 sys sys 944961294 19337
@@ -14251,7 +14253,7 @@ sys/src/cmd/usb/lib/usb.h - 664 sys sys 1165044715 7066
 sys/src/cmd/usb/lib/util.c - 664 sys sys 1091204978 523
 sys/src/cmd/usb/misc - 20000000775 sys sys 1091282306 0
 sys/src/cmd/usb/misc/mkfile - 664 sys sys 1167255850 374
-sys/src/cmd/usb/misc/usbmouse.c - 664 sys sys 1163722035 3603
+sys/src/cmd/usb/misc/usbmouse.c - 664 sys sys 1178824856 3755
 sys/src/cmd/usb/misc/usbprint - 775 sys sys 1167253831 314
 sys/src/cmd/usb/misc/usbprobe - 775 sys sys 1167253836 173
 sys/src/cmd/usb/mkfile - 664 sys sys 1091327562 354
@@ -15814,3 +15816,6 @@ usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
+386/bin/usb/usbmouse - 775 sys sys 1178853709 109673
+386/bin/auth/factotum - 775 sys sys 1178853707 321175
+386/bin/troff - 775 sys sys 1178853709 361158

+ 19 - 17
dist/replica/plan9.db

@@ -53,7 +53,7 @@
 386/bin/auth/debug - 775 sys sys 1168402268 101566
 386/bin/auth/disable - 775 sys sys 1020319057 146
 386/bin/auth/enable - 775 sys sys 1020319057 134
-386/bin/auth/factotum - 775 sys sys 1178568247 321180
+386/bin/auth/factotum - 775 sys sys 1178853707 321175
 386/bin/auth/fgui - 775 sys sys 1176520475 218973
 386/bin/auth/guard.srv - 775 sys sys 1178568248 143650
 386/bin/auth/iam - 775 sys sys 1085076981 50791
@@ -305,7 +305,7 @@
 386/bin/ip/ipconfig - 775 sys sys 1178654264 156933
 386/bin/ip/linklocal - 775 sys sys 1177530964 42790
 386/bin/ip/ping - 775 sys sys 1178568288 83220
-386/bin/ip/ppp - 775 sys sys 1178568289 218961
+386/bin/ip/ppp - 775 sys sys 1178826954 218964
 386/bin/ip/pppoe - 775 sys sys 1168402326 77787
 386/bin/ip/pptp - 775 sys sys 1169612026 127215
 386/bin/ip/pptpd - 775 sys sys 1178568289 124670
@@ -440,7 +440,7 @@
 386/bin/tprof - 775 sys sys 1172203056 297762
 386/bin/tr - 775 sys sys 1168402355 62088
 386/bin/trace - 775 sys sys 1178568308 180414
-386/bin/troff - 775 sys sys 1176520503 360243
+386/bin/troff - 775 sys sys 1178853709 361158
 386/bin/troff2html - 775 sys sys 1178568308 84524
 386/bin/tweak - 775 sys sys 1168402356 193256
 386/bin/unicode - 775 sys sys 1168402356 62747
@@ -482,7 +482,7 @@
 386/bin/usb - 20000000775 sys sys 1019538890 0
 386/bin/usb/usbaudio - 775 sys sys 1178568318 188012
 386/bin/usb/usbd - 775 sys sys 1176520513 130769
-386/bin/usb/usbmouse - 775 sys sys 1176520514 109605
+386/bin/usb/usbmouse - 775 sys sys 1178853709 109673
 386/bin/usb/usbprinter - 775 sys sys 1089408719 222
 386/bin/vac - 775 sys sys 1178568318 169885
 386/bin/vacfs - 775 sys sys 1178568319 174693
@@ -561,19 +561,19 @@
 386/lib/libgeometry.a - 664 sys sys 1168402366 50470
 386/lib/libhtml.a - 664 sys sys 1176432132 229152
 386/lib/libhttpd.a - 664 sys sys 1177283321 99734
-386/lib/libip.a - 664 sys sys 1178654265 34710
+386/lib/libip.a - 664 sys sys 1178826954 34710
 386/lib/libl.a - 664 sys sys 1168402367 5372
 386/lib/libmach.a - 664 sys sys 1173410637 785440
 386/lib/libmemdraw.a - 664 sys sys 1168402369 284092
 386/lib/libmemlayer.a - 664 sys sys 1168402369 47360
 386/lib/libmp.a - 664 sys sys 1176520528 79978
-386/lib/libndb.a - 664 sys sys 1176520529 64470
+386/lib/libndb.a - 664 sys sys 1178826955 64470
 386/lib/libplumb.a - 664 sys sys 1168402370 19408
 386/lib/libregexp.a - 664 sys sys 1168402370 37438
 386/lib/libscribble.a - 664 sys sys 1175972562 107238
 386/lib/libsec.a - 664 sys sys 1176520530 646724
 386/lib/libstdio.a - 664 sys sys 1176432133 126062
-386/lib/libsunrpc.a - 664 sys sys 1178508502 353148
+386/lib/libsunrpc.a - 664 sys sys 1178826956 353148
 386/lib/libthread.a - 664 sys sys 1176432134 71932
 386/lib/libventi.a - 664 sys sys 1168402374 97858
 386/mbr - 775 sys sys 1131317338 407
@@ -6068,7 +6068,7 @@ sys/include/frame.h - 664 sys sys 1147706379 2682
 sys/include/geometry.h - 664 sys sys 1014929063 2632
 sys/include/html.h - 664 sys sys 1128662123 15232
 sys/include/httpd.h - 664 sys sys 1177187803 5794
-sys/include/ip.h - 664 sys sys 1176499323 2978
+sys/include/ip.h - 664 sys sys 1178768502 2597
 sys/include/keyboard.h - 664 sys sys 1131637696 865
 sys/include/libc.h - 664 sys sys 1168306860 19851
 sys/include/libsec.h - 664 sys sys 1124709121 9345
@@ -7630,7 +7630,7 @@ sys/man/3/ether - 664 sys sys 1178597986 2890
 sys/man/3/floppy - 664 sys sys 954378905 881
 sys/man/3/fs - 664 sys sys 1175145095 3147
 sys/man/3/i82365 - 664 sys sys 954378906 884
-sys/man/3/ip - 664 sys sys 1178575371 25066
+sys/man/3/ip - 664 sys sys 1178768702 24744
 sys/man/3/kbmap - 664 sys sys 1131110122 1732
 sys/man/3/kprof - 664 sys sys 1018029972 1377
 sys/man/3/loopback - 664 sys sys 964662153 1995
@@ -7972,7 +7972,7 @@ sys/src/9/ip/ptclbsum.c - 664 sys sys 1022588099 1243
 sys/src/9/ip/rudp.c - 664 sys sys 1055700790 21415
 sys/src/9/ip/tcp.c - 664 sys sys 1170031827 65877
 sys/src/9/ip/tripmedium.c - 664 sys sys 1045063515 7136
-sys/src/9/ip/udp.c - 664 sys sys 1178057621 13132
+sys/src/9/ip/udp.c - 664 sys sys 1178817924 13317
 sys/src/9/mkfile - 664 sys sys 1063857477 205
 sys/src/9/mtx - 20000000775 sys sys 1123676466 0
 sys/src/9/mtx/clock.c - 664 sys sys 1032053278 1293
@@ -8003,6 +8003,7 @@ sys/src/9/mtx/trap.c - 664 sys sys 1105030157 15882
 sys/src/9/mtx/uarti8250.c - 664 sys sys 1018721288 11590
 sys/src/9/pc - 20000000775 sys sys 1161233143 0
 sys/src/9/pc/a100p.cp - 444 sys sys 1159735144 21984
+sys/src/9/pc/ahci.h - 664 sys sys 1178833481 6297
 sys/src/9/pc/apbootstrap.s - 664 sys sys 1131293655 3037
 sys/src/9/pc/apic.c - 664 sys sys 1174415344 8991
 sys/src/9/pc/apm.c - 664 sys sys 1131290210 3723
@@ -8013,7 +8014,7 @@ sys/src/9/pc/bios32.c - 664 sys sys 1173287378 3029
 sys/src/9/pc/cga.c - 664 sys sys 1015014513 1843
 sys/src/9/pc/dat.h - 664 sys sys 1173289271 6917
 sys/src/9/pc/devarch.c - 664 sys sys 1168315311 19342
-sys/src/9/pc/devether.c - 664 sys sys 1178548254 10316
+sys/src/9/pc/devether.c - 664 sys sys 1178823613 10489
 sys/src/9/pc/devfloppy.c - 664 sys sys 1142958305 20139
 sys/src/9/pc/devi82365.c - 664 sys sys 1146318335 20504
 sys/src/9/pc/devlm78.c - 664 sys sys 1128255048 6291
@@ -8098,6 +8099,7 @@ sys/src/9/pc/screen.c - 664 sys sys 1136336092 13971
 sys/src/9/pc/screen.h - 664 sys sys 1147023549 4256
 sys/src/9/pc/sd53c8xx.c - 664 sys sys 1170456695 55276
 sys/src/9/pc/sd53c8xx.n - 664 sys sys 1131290556 12657
+sys/src/9/pc/sd63xxesb.c - 664 sys sys 1178836359 35774
 sys/src/9/pc/sdata.c - 664 sys sys 1175564140 52809
 sys/src/9/pc/sdmv50xx.c - 664 sys sys 1177393607 33810
 sys/src/9/pc/sdmylex.c - 664 sys sys 1171321627 28237
@@ -8196,14 +8198,14 @@ sys/src/9/port/mkrootall - 775 sys sys 1055954696 386
 sys/src/9/port/mkrootc - 775 sys sys 1055954695 717
 sys/src/9/port/mksystab - 664 sys sys 1014931176 783
 sys/src/9/port/mul64fract.c - 664 sys sys 1071671674 867
-sys/src/9/port/netif.c - 664 sys sys 1170456606 13474
+sys/src/9/port/netif.c - 664 sys sys 1178831077 13474
 sys/src/9/port/netif.h - 664 sys sys 1066514947 2975
 sys/src/9/port/page.c - 664 sys sys 1131636090 11128
 sys/src/9/port/parse.c - 664 sys sys 1014931177 2026
 sys/src/9/port/pgrp.c - 664 sys sys 1138458260 4760
 sys/src/9/port/portclock.c - 664 sys sys 1146746630 4276
 sys/src/9/port/portdat.h - 664 sys sys 1155995676 22703
-sys/src/9/port/portfns.h - 664 sys sys 1146746630 11059
+sys/src/9/port/portfns.h - 664 sys sys 1178831066 11059
 sys/src/9/port/portmkfile - 664 sys sys 1173788325 2069
 sys/src/9/port/print.c - 664 sys sys 1014931178 227
 sys/src/9/port/proc.c - 664 sys sys 1176658321 28742
@@ -9554,7 +9556,7 @@ sys/src/cmd/auth/factotum/rpc.c - 664 sys sys 1107633794 11167
 sys/src/cmd/auth/factotum/rsa.c - 664 sys sys 1107706104 3416
 sys/src/cmd/auth/factotum/secstore.c - 664 sys sys 1140272941 14955
 sys/src/cmd/auth/factotum/sshrsa.c - 664 sys sys 1107633793 3416
-sys/src/cmd/auth/factotum/util.c - 664 sys sys 1143694878 18460
+sys/src/cmd/auth/factotum/util.c - 664 sys sys 1178832638 18451
 sys/src/cmd/auth/factotum/wep.c - 664 sys sys 1107706104 2140
 sys/src/cmd/auth/guard.srv.c - 664 sys sys 1172776773 2873
 sys/src/cmd/auth/iam.c - 664 sys sys 1015008430 841
@@ -12533,7 +12535,7 @@ sys/src/cmd/ip/ppp/dotest - 775 sys sys 944961006 152
 sys/src/cmd/ip/ppp/ipaux.c - 664 sys sys 1125529107 2328
 sys/src/cmd/ip/ppp/mkfile - 664 sys sys 1063897576 352
 sys/src/cmd/ip/ppp/mppc.c - 664 sys sys 1015090267 16624
-sys/src/cmd/ip/ppp/ppp.c - 664 sys sys 1143759338 59898
+sys/src/cmd/ip/ppp/ppp.c - 664 sys sys 1178810697 59924
 sys/src/cmd/ip/ppp/ppp.h - 664 sys sys 1091904423 8284
 sys/src/cmd/ip/ppp/testppp.c - 664 sys sys 1045505281 3011
 sys/src/cmd/ip/ppp/thw.c - 664 sys sys 1015090268 5962
@@ -13593,7 +13595,7 @@ sys/src/cmd/troff/n4.c - 664 sys sys 984718893 12310
 sys/src/cmd/troff/n5.c - 664 sys sys 944961293 14261
 sys/src/cmd/troff/n6.c - 664 sys sys 944961294 4862
 sys/src/cmd/troff/n7.c - 664 sys sys 944961294 12476
-sys/src/cmd/troff/n8.c - 664 sys sys 944961294 10197
+sys/src/cmd/troff/n8.c - 664 sys sys 1178823422 10250
 sys/src/cmd/troff/n9.c - 664 sys sys 944961294 9076
 sys/src/cmd/troff/ni.c - 664 sys sys 944961294 8492
 sys/src/cmd/troff/suftab.c - 664 sys sys 944961294 19337
@@ -14251,7 +14253,7 @@ sys/src/cmd/usb/lib/usb.h - 664 sys sys 1165044715 7066
 sys/src/cmd/usb/lib/util.c - 664 sys sys 1091204978 523
 sys/src/cmd/usb/misc - 20000000775 sys sys 1091282306 0
 sys/src/cmd/usb/misc/mkfile - 664 sys sys 1167255850 374
-sys/src/cmd/usb/misc/usbmouse.c - 664 sys sys 1163722035 3603
+sys/src/cmd/usb/misc/usbmouse.c - 664 sys sys 1178824856 3755
 sys/src/cmd/usb/misc/usbprint - 775 sys sys 1167253831 314
 sys/src/cmd/usb/misc/usbprobe - 775 sys sys 1167253836 173
 sys/src/cmd/usb/mkfile - 664 sys sys 1091327562 354

+ 19 - 0
dist/replica/plan9.log

@@ -48795,3 +48795,22 @@
 1178654412 1 c 386/bin/ip/rarpd - 775 sys sys 1178654264 111254
 1178654412 2 c 386/bin/ndb/cs - 775 sys sys 1178654265 149084
 1178654412 3 c 386/lib/libip.a - 664 sys sys 1178654265 34710
+1178769605 0 c sys/include/ip.h - 664 sys sys 1178768502 2597
+1178769605 1 c sys/man/3/ip - 664 sys sys 1178768702 24744
+1178811007 0 c sys/src/cmd/ip/ppp/ppp.c - 664 sys sys 1178810697 59924
+1178818206 0 c sys/src/9/ip/udp.c - 664 sys sys 1178817924 13317
+1178823609 0 c sys/src/9/pc/devether.c - 664 sys sys 1178823613 10489
+1178823609 1 c sys/src/cmd/troff/n8.c - 664 sys sys 1178823422 10250
+1178825407 0 c sys/src/cmd/usb/misc/usbmouse.c - 664 sys sys 1178824856 3755
+1178827205 0 c 386/bin/ip/ppp - 775 sys sys 1178826954 218964
+1178827205 1 c 386/lib/libip.a - 664 sys sys 1178826954 34710
+1178827205 2 c 386/lib/libndb.a - 664 sys sys 1178826955 64470
+1178827205 3 c 386/lib/libsunrpc.a - 664 sys sys 1178826956 353148
+1178832606 0 c sys/src/9/port/netif.c - 664 sys sys 1178831077 13474
+1178832606 1 c sys/src/9/port/portfns.h - 664 sys sys 1178831066 11059
+1178832606 2 c sys/src/cmd/auth/factotum/util.c - 664 sys sys 1178832638 18451
+1178834406 0 a sys/src/9/pc/ahci.h - 664 sys sys 1178833481 6297
+1178838006 0 a sys/src/9/pc/sd63xxesb.c - 664 sys sys 1178836359 35774
+1178854206 0 c 386/bin/usb/usbmouse - 775 sys sys 1178853709 109673
+1178854206 1 c 386/bin/auth/factotum - 775 sys sys 1178853707 321175
+1178854206 2 c 386/bin/troff - 775 sys sys 1178853709 361158

+ 11 - 7
sys/src/9/ip/udp.c

@@ -217,7 +217,7 @@ udpkick(void *x, Block *bp)
 		rport = nhgets(bp->rp);
 		bp->rp += 2+2;			/* Ignore local port */
 		break;
-	case 6:
+	case 6:					/* OBS */
 		/* get user specified addresses */
 		bp = pullupblock(bp, UDP_USEAD6);
 		if(bp == nil)
@@ -244,9 +244,9 @@ udpkick(void *x, Block *bp)
 		else
 			version = 6;
 	} else {
-		if( (memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
-			memcmp(c->laddr, v4prefix, IPv4off) == 0)
-			|| ipcmp(c->raddr, IPnoaddr) == 0)
+		if((memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
+		    memcmp(c->laddr, v4prefix, IPv4off) == 0) ||
+		    ipcmp(c->raddr, IPnoaddr) == 0)
 			version = 4;
 		else
 			version = 6;
@@ -507,7 +507,7 @@ udpiput(Proto *udp, Ipifc *ifc, Block *bp)
 		hnputs(p, rport); p += 2;
 		hnputs(p, lport);
 		break;
-	case 6:
+	case 6:					/* OBS */
 		/* pass the src address */
 		bp = padblock(bp, UDP_USEAD6);
 		p = bp->rp;
@@ -541,11 +541,15 @@ udpctl(Conv *c, char **f, int n)
 
 	ucb = (Udpcb*)c->ptcl;
 	if(n == 1){
-		if(strcmp(f[0], "oldheaders") == 0){
+		if(strcmp(f[0], "oldheaders") == 0){	/* OBS */
 			ucb->headers = 6;
+			if (up)
+				print("program %s wrote `oldheaders' to udp "
+					"ctl file; fix or recompile it\n",
+					up->text);
 			return nil;
 		} else if(strcmp(f[0], "headers") == 0){
-			ucb->headers = 7;
+			ucb->headers = 7;	/* new headers format */
 			return nil;
 		}
 	}

+ 275 - 0
sys/src/9/pc/ahci.h

@@ -0,0 +1,275 @@
+/*
+ * advanced host controller interface (sata)
+ * © 2007  coraid, inc
+ */
+
+/* ata errors */
+enum{
+	Emed	= 1<<0,		/* media error */
+	Enm	= 1<<1,		/* no media */
+	Eabrt	= 1<<2,		/* abort */
+	Emcr	= 1<<3,		/* media change request */
+	Eidnf	= 1<<4,		/* no user-accessible address */
+	Emc	= 1<<5,		/* media change */
+	Eunc	= 1<<6,		/* data error */
+	Ewp	= 1<<6,		/* write protect */
+	Eicrc	= 1<<7,		/* interface crc error */
+
+	Efatal	= Eidnf|Eicrc,	/* must sw reset. */
+};
+
+/* ata status */
+enum{
+	ASerr	= 1<<0,		/* error */
+	ASdrq	= 1<<3,		/* request */
+	ASdf	= 1<<5,		/* fault */
+	ASdrdy	= 1<<6,		/* ready */
+	ASbsy	= 1<<7,		/* busy */
+
+	ASobs	= 1<<1|1<<2|1<<4,
+};
+
+/* pci configuration */
+enum{
+	Abar	= 5,
+};
+
+/*
+ * ahci memory configuration
+ *
+ * 0000-0023	generic host control
+ * 0024-009f	reserved
+ * 00a0-00ff	vendor specific.
+ * 0100-017f	port 0
+ * ...
+ * 1080-1100	port 31
+ */
+
+/* cap bits: supported features */
+enum{
+	Hs64a	= 1<<31,	/* 64-bit addressing */
+	Hsncq	= 1<<30,	/* ncq */
+	Hssntf	= 1<<29,	/* snotification reg. */
+	Hsmps	= 1<<28,	/* mech pres switch */
+	Hsss	= 1<<27,	/* staggered spinup */
+	Hsalp	= 1<<26,	/* aggressive link pm */
+	Hsal	= 1<<25,	/* activity led */
+	Hsclo	= 1<<24,	/* command-list override */
+	Hiss	= 1<<20,	/* for interface speed. */
+//	Hsnzo	= 1<<19,
+	Hsam	= 1<<18,	/* ahci-mode only */
+	Hspm	= 1<<17,	/* port multiplier */
+//	Hfbss	= 1<<16,
+	Hpmb	= 1<<15,	/* multiple-block pio */
+	Hssc	= 1<<14,	/* slumber state */
+	Hpsc	= 1<<13,	/* partial-slumber state */
+	Hncs	= 1<<8,		/* n command slots */
+	Hcccs	= 1<<7,		/* coal */
+	Hems	= 1<<6,		/* enclosure mgmt. */
+	Hsxs	= 1<<5,		/* external sata. */
+	Hnp	= 1<<0,		/* n ports */
+};
+
+/* ghc bits */
+enum{
+	Hae	= 1<<31,	/* enable ahci */
+	Hie	= 1<<1,		/* " interrupts */
+	Hhr	= 1<<0,		/* hba reset */
+};
+
+typedef struct{
+	u32int	cap;
+	u32int	ghc;
+	u32int	isr;
+	u32int	pi;	/* ports implemented */
+	u32int	ver;
+	u32int	ccc;	/* coaleasing control */
+	u32int	cccports;
+	u32int	emloc;
+	u32int	emctl;
+} Ahba;
+
+enum{
+	Acpds	= 1<<31,	/* cold port detect status */
+	Atfes	= 1<<30,	/* task file error status */
+	Ahbfs	= 1<<29,	/* hba fatal */
+	Ahbds	= 1<<28,	/* hba error (parity error) */
+	Aifs	= 1<<27,	/* interface fatal  §6.1.2 */
+	Ainfs	= 1<<26,	/* interface error (recovered) */
+	Aofs	= 1<<24,	/* too many bytes from disk. */
+	Aipms	= 1<<23,	/* incorrect prt mul status */
+	Aprcs	= 1<<22,	/* PhyRdy change status Pxserr.diag.n */
+	Adpms	= 1<<7,		/* mechanical presence status */
+	Apcs 	= 1<<6,		/* port connect  diag.x */
+	Adps 	= 1<<5,		/* descriptor processed */
+	Aufs 	= 1<<4,		/* unknown fis diag.f */
+	Asdbs	= 1<<3,		/* set device bits fis received w/ i bit set */
+	Adss	= 1<<2,		/* dma setup */
+	Apio	= 1<<1,		/* pio setup fis */
+	Adhrs	= 1<<0,		/* device to host register fis. */
+
+	IEM	= Acpds|Atfes|Ahbds|Ahbfs|Ahbds|Aifs|Ainfs|Aprcs|Apcs|Adps|
+		  Aufs|Asdbs|Adss|Adhrs,
+	Ifatal	= Atfes|Ahbfs|Ahbds|Aifs,
+};
+
+/* serror bits */
+enum{
+	SerrX	= 1<<26,	/* exchanged */
+	SerrF	= 1<<25,	/* unknown fis */
+	SerrT	= 1<<24,	/* transition error */
+	SerrS	= 1<<23,	/* link sequence */
+	SerrH	= 1<<22,	/* handshake */
+	SerrC	= 1<<21,	/* crc */
+	SerrD	= 1<<20,	/* not used by ahci */
+	SerrB	= 1<<19,	/* 10-tp-8 decode */
+	SerrW	= 1<<18,	/* comm wake */
+	SerrI	= 1<<17,	/* phy internal */
+	SerrN	= 1<<16,	/* phyrdy change */
+
+	ErrE	= 1<<11,	/* internal */
+	ErrP	= 1<<10,	/* ata protocol violation */
+	ErrC	= 1<<9,		/* communication */
+	ErrT	= 1<<8,		/* transient */
+	ErrM	= 1<<1,		/* recoverd comm */
+	ErrI	= 1<<0,		/* recovered data integrety */
+
+	ErrAll	= ErrE|ErrP|ErrC|ErrT|ErrM|ErrI,
+	SerrAll	= SerrX|SerrF|SerrT|SerrS|SerrH|SerrC|SerrD|SerrB|SerrW|SerrI|
+		  SerrN|ErrAll,
+	SerrBad	= 0x7f<<19,
+};
+
+/* cmd register bits */
+enum{
+	Aicc	= 1<<28,	/* interface communcations control. 4 bits */
+	Aasp	= 1<<27,	/* agressive slumber & partial sleep */
+	Aalpe 	= 1<<26,	/* agressive link pm enable */
+	Adlae	= 1<<25,	/* drive led on atapi */
+	Aatapi	= 1<<24,	/* device is atapi */
+	Aesp	= 1<<21,	/* external sata port */
+	Acpd	= 1<<20,	/* cold presence detect */
+	Ampsp	= 1<<19,	/* mechanical pres. */
+	Ahpcp	= 1<<18,	/* hot plug capable */
+	Apma	= 1<<17,	/* pm attached */
+	Acps	= 1<<16,	/* cold presence state */
+	Acr	= 1<<15,	/* cmdlist running */
+	Afr	= 1<<14,	/* fis running */
+	Ampss	= 1<<13,	/* mechanical presence switch state */
+	Accs	= 1<<8,		/* current command slot 12:08 */
+	Afre	= 1<<4,		/* fis enable receive. */
+	Aclo	= 1<<3,		/* command list override */
+	Apod	= 1<<2,		/* power on device (needs cold-pres. detect) */
+	Asud	= 1<<1,		/* spin-up device;  requires ss capability. */
+	Ast	= 1<<0,		/* start */
+
+	Arun	= Ast|Acr|Afre|Afr,
+};
+
+/* ctl register bits */
+enum{
+	Aipm	= 1<<8,		/* interface power mgmt. 3=off */
+	Aspd	= 1<<4,
+	Adet	= 1<<0,		/* device detcection. */
+};
+
+#define	sstatus	scr0
+#define	sctl	scr2
+#define	serror	scr1
+#define	sactive	scr3
+
+typedef struct{
+	u32int	list;		/* PxCLB must be 1kb aligned. */
+	u32int	listhi;
+	u32int	fis;		/* 256-byte aligned. */
+	u32int	fishi;
+	u32int	isr;
+	u32int	ie;		/* interrupt enable */
+	u32int	cmd;
+	u32int	res1;
+	u32int	task;
+	u32int	sig;
+	u32int	scr0;
+	u32int	scr2;
+	u32int	scr1;
+	u32int	scr3;
+	u32int	ci;		/* command issue */
+	u32int	ntf;
+	uchar	res2[8];
+	u32int	vendor;
+}Aport;
+
+/* in host's memory; not memory mapped */
+typedef struct{
+	uchar	*base;
+	uchar	*d;
+	uchar	*p;
+	uchar	*r;
+	uchar	*u;
+	u32int	*devicebits;
+}Afis;
+
+enum{
+	Lprdtl	= 1<<16,	/* physical region descriptor table len */
+	Lpmp	= 1<<12,	/* port multiplier port */
+	Lclear	= 1<<10,	/* clear busy on R_OK */
+	Lbist	= 1<<9,
+	Lreset	= 1<<8,
+	Lpref	= 1<<7,		/* prefetchable */
+	Lwrite	= 1<<6,
+	Latapi	= 1<<5,
+	Lcfl	= 1<<0,		/* command fis length in double words */
+};
+
+/* in hosts memory; memory mapped */
+typedef struct{
+	u32int	flags;
+	u32int	len;
+	u32int	ctab;
+	u32int	ctabhi;
+	uchar	reserved[16];
+}Alist;
+
+typedef struct{
+	u32int	dba;
+	u32int	dbahi;
+	u32int	pad;
+	u32int	count;
+}Aprdt;
+
+typedef struct{
+	uchar	cfis[0x40];
+	uchar	atapi[0x10];
+	uchar	pad[0x30];
+	Aprdt	prdt;
+}Actab;
+
+enum{
+	Ferror	= 1,
+	Fdone	= 2,
+};
+
+enum{
+	Dllba 	= 1,
+	Dsmart	= 1<<1,
+	Dpower	= 1<<2,
+	Dnop	= 1<<3,
+	Datapi	= 1<<4,
+	Datapi16= 1<<5,
+};
+
+typedef struct{
+	QLock;
+	Rendez;
+	uchar	flag;
+	uchar	feat;
+	uchar	smart;
+	Afis	fis;
+	Alist	*list;
+	Actab	*ctab;
+}Aportm;
+
+typedef struct{
+	Aport	*p;
+	Aportm	*m;
+}Aportc;

+ 22 - 15
sys/src/9/pc/devether.c

@@ -4,6 +4,7 @@
 #include "dat.h"
 #include "fns.h"
 #include "io.h"
+#include "pool.h"
 #include "ureg.h"
 #include "../port/error.h"
 #include "../port/netif.h"
@@ -262,7 +263,7 @@ etherwrite(Chan* chan, void* buf, long n, vlong)
 		free(cb);
 		if(ether->ctl!=nil)
 			return ether->ctl(ether,buf,n);
-			
+
 		error(Ebadctl);
 	}
 
@@ -358,7 +359,8 @@ parseether(uchar *to, char *from)
 static Ether*
 etherprobe(int cardno, int ctlrno)
 {
-	int i;
+	int i, lg;
+	ulong mb, bsz;
 	Ether *ether;
 	char buf[128], name[32];
 
@@ -425,20 +427,25 @@ etherprobe(int cardno, int ctlrno)
 	sprint(buf+i, "\n");
 	print(buf);
 
-	if(ether->mbps >= 1000){
-		netifinit(ether, name, Ntypes, 512*1024);
-		if(ether->oq == 0)
-			ether->oq = qopen(512*1024, Qmsg, 0, 0);
-	}else if(ether->mbps >= 100){
-		netifinit(ether, name, Ntypes, 256*1024);
-		if(ether->oq == 0)
-			ether->oq = qopen(256*1024, Qmsg, 0, 0);
-	}else{
-		netifinit(ether, name, Ntypes, 128*1024);
-		if(ether->oq == 0)
-			ether->oq = qopen(128*1024, Qmsg, 0, 0);
+	/* compute log10(ether->mbps) into lg */
+	for(lg = 0, mb = ether->mbps; mb >= 10; lg++)
+		mb /= 10;
+	if (lg > 0)
+		lg--;
+	if (lg > 14)			/* 2^(14+17) = 2⁳ⁱ */
+		lg = 14;
+	/* allocate larger output queues for higher-speed interfaces */
+	bsz = 1UL << (lg + 17);		/* 2ⁱ⁷ = 128K, bsz = 2ⁿ × 128K */
+	while (bsz > mainmem->maxsize && bsz >= 128*1024)
+		bsz /= 2;
+
+	netifinit(ether, name, Ntypes, bsz);
+	while (ether->oq == nil && bsz >= 128*1024) {
+		bsz /= 2;
+		ether->oq = qopen(bsz, Qmsg, 0, 0);
+		ether->limit = bsz;
 	}
-	if(ether->oq == 0)
+	if(ether->oq == nil)
 		panic("etherreset %s", name);
 	ether->alen = Eaddrlen;
 	memmove(ether->addr, ether->ea, Eaddrlen);

+ 2120 - 0
sys/src/9/pc/sd63xxesb.c

@@ -0,0 +1,2120 @@
+/*
+ * intel 63[12]?esb ahci sata controller
+ * copyright © 2007 coraid, inc.
+ */
+
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+#include "../port/sd.h"
+#include "ahci.h"
+
+#define	dprint(...)	if(debug == 1)	iprint(__VA_ARGS__); else USED(debug)
+#define	idprint(...)	if(prid == 1)	print(__VA_ARGS__); else USED(prid)
+#define	aprint(...)	if(datapi == 1)	iprint(__VA_ARGS__); else USED(datapi);
+
+enum{
+	NCtlr	= 4,
+	NCtlrdrv= 32,
+	NDrive	= NCtlr*NCtlrdrv,
+
+	Read	= 0,
+	Write,
+};
+
+/* pci space configurtion */
+enum{
+	Pmap	= 0x90,
+	Ppcs	= 0x91,
+	Prev	= 0xa8,
+};
+
+enum{
+	Dnull,
+	Dmissing,
+	Dnew,
+	Dready,
+	Derror,
+	Dreset,
+	Doffline,
+	Dportreset,
+	Dlast,
+};
+
+static char *diskstates[Dlast] = {
+	"null",
+	"missing",
+	"new",
+	"ready",
+	"error",
+	"reset",
+	"offline",
+	"portreset",
+};
+
+extern SDifc sd63xxesbifc;
+typedef struct Ctlr Ctlr;
+
+enum{
+	DMautoneg,
+	DMsatai,
+	DMsataii,
+};
+
+static char *modename[] = {
+	"auto",
+	"satai",
+	"sataii",
+};
+
+static char *flagname[] = {
+	"llba",
+	"smart",
+	"power",
+	"nop",
+	"atapi",
+	"atapi16",
+};
+
+typedef struct{
+	Lock;
+
+	Ctlr	*ctlr;
+	SDunit	*unit;
+	char	name[10];
+	Aport	*port;
+	Aportm	portm;
+	Aportc	portc;		/* redundant ptr to port and portm. */
+
+	uchar	mediachange;
+	uchar	state;
+	uchar	smartrs;
+
+	uvlong	sectors;
+	ulong	intick;
+	int	wait;
+	uchar	mode;		/* DMautoneg, satai or sataii. */
+	uchar	active;
+
+	char	serial[20+1];
+	char	firmware[8+1];
+	char	model[40+1];
+
+	ushort	info[0x200];
+
+	int	driveno;	/* ctlr*NCtlrdrv + unit */
+	/* ctlr port # != driveno when not all ports are enabled */
+	int	portno;
+}Drive;
+
+struct Ctlr{
+	Lock;
+
+	int	irq;
+	int	tbdf;
+	int	enabled;
+	SDev	*sdev;
+	Pcidev	*pci;
+
+	uchar	*mmio;
+	ulong	*lmmio;
+	Ahba	*hba;
+
+	Drive	rawdrive[NCtlrdrv];
+	Drive*	drive[NCtlrdrv];
+	int	ndrive;
+};
+
+static	Ctlr	iactlr[NCtlr];
+static	SDev	sdevs[NCtlr];
+static	int	niactlr;
+
+static	Drive	*iadrive[NDrive];
+static	int	niadrive;
+
+static	int	debug;
+static	int	prid = 1;
+static	int	datapi = 1;
+
+static char stab[] = {
+[0]	'i', 'm',
+[8]	't', 'c', 'p', 'e',
+[16]	'N', 'I', 'W', 'B', 'D', 'C', 'H', 'S', 'T', 'F', 'X'
+};
+
+static void
+serrstr(ulong r, char *s, char *e)
+{
+	int i;
+
+	e -= 3;
+	for(i = 0; i < nelem(stab) && s < e; i++)
+		if((r & (1<<i)) && stab[i]){
+			*s++ = stab[i];
+			if(SerrBad & (1<<i))
+				*s++ = '*';
+		}
+	*s = 0;
+}
+
+static char ntab[] = "0123456789abcdef";
+
+static void
+preg(uchar *reg, int n)
+{
+	int i;
+	char buf[25*3+1], *e;
+
+	e = buf;
+	for(i = 0; i < n; i++){
+		*e++ = ntab[reg[i]>>4];
+		*e++ = ntab[reg[i]&0xf];
+		*e++ = ' ';
+	}
+	*e++ = '\n';
+	*e = 0;
+	dprint(buf);
+}
+
+static void
+dreg(char *s, Aport *p)
+{
+	dprint("%stask=%ux; cmd=%ux; ci=%ux; is=%ux\n", s, p->task, p->cmd,
+		p->ci, p->isr);
+}
+
+static void
+esleep(int ms)
+{
+	if(waserror())
+		return;
+	tsleep(&up->sleep, return0, 0, ms);
+	poperror();
+}
+
+typedef struct{
+	Aport	*p;
+	int	i;
+}Asleep;
+
+static int
+ahciclear(void *v)
+{
+	Asleep *s;
+
+	s = v;
+	return (s->p->ci & s->i) == 0;
+}
+
+static void
+aesleep(Aportm *m, Asleep *a, int ms)
+{
+	if(waserror())
+		return;
+	tsleep(m, ahciclear, a, ms);
+	poperror();
+}
+
+static int
+ahciwait(Aportc *c, int ms)
+{
+	Asleep as;
+	Aport *p;
+
+	p = c->p;
+	p->ci = 1;
+	as.p = p;
+	as.i = 1;
+	aesleep(c->m, &as, ms);
+	if((p->task&1) == 0 && p->ci == 0)
+		return 0;
+	dreg("ahciwait timeout ", c->p);
+	return -1;
+}
+
+static int
+nop(Aportc *pc)
+{
+	uchar *c;
+	Actab *t;
+	Alist *l;
+
+	if((pc->m->feat&Dnop) == 0)
+		return -1;
+
+	t = pc->m->ctab;
+	c = t->cfis;
+
+	memset(c, 0, 0x20);
+	c[0] = 0x27;
+	c[1] = 0x80;
+	c[2] = 0x00;
+	c[7] = 0xa0;		/* obsolete device bits */
+
+	l = pc->m->list;
+	l->flags = Lwrite|0x5;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	return ahciwait(pc, 3*1000);
+}
+
+static int
+setfeatures(Aportc *pc, uchar f)
+{
+	uchar *c;
+	Actab *t;
+	Alist *l;
+
+	t = pc->m->ctab;
+	c = t->cfis;
+
+	memset(c, 0, 0x20);
+	c[0] = 0x27;
+	c[1] = 0x80;
+	c[2] = 0xef;
+	c[3] = f;
+	c[7] = 0xa0;		/* obsolete device bits */
+
+	l = pc->m->list;
+	l->flags = Lwrite|0x5;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	return ahciwait(pc, 3*1000);
+}
+
+static int
+setudmamode(Aportc *pc, uchar f)
+{
+	uchar *c;
+	Actab *t;
+	Alist *l;
+
+	t = pc->m->ctab;
+	c = t->cfis;
+
+	memset(c, 0, 0x20);
+	c[0] = 0x27;
+	c[1] = 0x80;
+	c[2] = 0xef;
+	c[3] = 3;		/* set transfer mode */
+	c[7] = 0xa0;		/* obsolete device bits */
+	c[12] = 0x40|f;		/* sector count */
+
+	l = pc->m->list;
+	l->flags = Lwrite|0x5;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	return ahciwait(pc, 3*1000);
+}
+
+static void
+asleep(int ms)
+{
+	if(up == nil)
+		delay(ms);
+	else
+		esleep(ms);
+}
+
+static int
+ahciportreset(Aportc *c)
+{
+	u32int *cmd, i;
+	Aport *p;
+
+	p = c->p;
+	cmd = &p->cmd;
+	*cmd &= ~(Afre|Ast);
+	for(i = 0; i < 500; i += 25){
+		if((*cmd & Acr) == 0)
+			break;
+		asleep(25);
+	}
+
+	p->sctl = 1 | (p->sctl & ~7);
+	delay(1);
+	p->sctl &= ~7;
+	return 0;
+}
+
+static int
+smart(Aportc *pc, int n)
+{
+	uchar *c;
+	Actab *t;
+	Alist *l;
+
+	if((pc->m->feat&Dsmart) == 0)
+		return -1;
+
+	t = pc->m->ctab;
+	c = t->cfis;
+
+	memset(c, 0, 0x20);
+	c[0] = 0x27;
+	c[1] = 0x80;
+	c[2] = 0xb0;
+	c[3] = 0xd8+n;		/* able smart */
+	c[5] = 0x4f;
+	c[6] = 0xc2;
+	c[7] = 0xa0;
+
+	l = pc->m->list;
+	l->flags = Lwrite | 0x5;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	if(ahciwait(pc, 1000) == -1 || pc->p->task & (1|32)){
+		dprint("smart fail %ux\n", pc->p->task);
+//		preg(pc->m->fis.r, 20);
+		return -1;
+	}
+	if(n)
+		return 0;
+	return 1;
+}
+
+static int
+smartrs(Aportc *pc)
+{
+	uchar *c;
+	Actab *t;
+	Alist *l;
+
+	t = pc->m->ctab;
+	c = t->cfis;
+
+	memset(c, 0, 0x20);
+	c[0] = 0x27;
+	c[1] = 0x80;
+	c[2] = 0xb0;
+	c[3] = 0xda;		/* return smart status */
+	c[5] = 0x4f;
+	c[6] = 0xc2;
+	c[7] = 0xa0;
+
+	l = pc->m->list;
+	l->flags = Lwrite | 0x5;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	c = pc->m->fis.r;
+	if(ahciwait(pc, 1000) == -1 || pc->p->task & (1|32)){
+		dprint("smart fail %ux\n", pc->p->task);
+		preg(c, 20);
+		return -1;
+	}
+	if(c[5] == 0x4f && c[6] == 0xc2)
+		return 1;
+	return 0;
+}
+
+static int
+flushcache(Aportc *pc)
+{
+	uchar *c, llba;
+	Actab *t;
+	Alist *l;
+	static uchar tab[2] = {0xe7, 0xea};
+
+	llba = pc->m->feat & Dllba? 1: 0;
+	t = pc->m->ctab;
+	c = t->cfis;
+
+	memset(c, 0, 0x20);
+	c[0] = 0x27;
+	c[1] = 0x80;
+	c[2] = tab[llba];
+	c[7] = 0xa0;
+
+	l = pc->m->list;
+	l->flags = Lwrite | 0x5;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	if(ahciwait(pc, 60000) == -1 || pc->p->task & (1|32)){
+		dprint("flushcache fail %ux\n", pc->p->task);
+//		preg( pc->m->fis.r, 20);
+		return -1;
+	}
+	return 0;
+}
+
+static ushort
+gbit16(void *a)
+{
+	ushort j;
+	uchar *i;
+
+	i = a;
+	j  = i[1] << 8;
+	j |= i[0];
+	return j;
+}
+
+static u32int
+gbit32(void *a)
+{
+	uchar *i;
+	u32int j;
+
+	i = a;
+	j  = i[3] << 24;
+	j |= i[2] << 16;
+	j |= i[1] << 8;
+	j |= i[0];
+	return j;
+}
+
+static uvlong
+gbit64(void *a)
+{
+	uchar *i;
+
+	i = a;
+	return (uvlong)gbit32(i+4) << 32 | gbit32(a);
+}
+
+static int
+ahciidentify0(Aportc *pc, void *id, int atapi)
+{
+	uchar *c;
+	Actab *t;
+	Alist *l;
+	Aprdt *p;
+	static uchar tab[] = {0xec, 0xa1};
+
+	t = pc->m->ctab;
+	c = t->cfis;
+
+	memset(c, 0, 0x20);
+	c[0] = 0x27;
+	c[1] = 0x80;
+	c[2] = tab[atapi];
+	c[7] = 0xa0;		/* obsolete device bits */
+
+	l = pc->m->list;
+	l->flags = 1<<16 | 0x5;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	memset(id, 0, 0x100);
+	p = &t->prdt;
+	p->dba = PCIWADDR(id);
+	p->dbahi = 0;
+	p->count = 1<<31 | (0x200-2) | 1;
+
+	return ahciwait(pc, 3*1000);
+}
+
+static vlong
+ahciidentify(Aportc *pc, ushort *id)
+{
+	int i, sig;
+	vlong s;
+	Aportm *m;
+
+	m = pc->m;
+	m->feat = 0;
+	m->smart = 0;
+	i = 0;
+	sig = pc->p->sig >> 16;
+	if(sig == 0xeb14 || sig == 0x9669){
+		m->feat |= Datapi;
+		i = 1;
+	}
+	if(ahciidentify0(pc, id, i) == -1)
+		return -1;
+
+	i = gbit16(id+83) | gbit16(id+86);
+	if(i & (1<<10)){
+		m->feat |= Dllba;
+		s = gbit64(id+100);
+	}else
+		s = gbit32(id+60);
+
+	if(m->feat&Datapi){
+		i = gbit16(id+0);
+		if(i&1)
+			m->feat |= Datapi16;
+	}
+
+	i = gbit16(id+83);
+	if((i>>14) == 1) {
+		if(i & (1<<3))
+			m->feat |= Dpower;
+		i = gbit16(id+82);
+		if(i & 1)
+			m->feat |= Dsmart;
+		if(i & (1<<14))
+			m->feat |= Dnop;
+	}
+	return s;
+}
+
+static int
+ahciquiet(Aport *a)
+{
+	u32int *p, i;
+
+	p = &a->cmd;
+	*p &= ~Ast;
+	for(i = 0; i < 500; i += 50){
+		if((*p & Acr) == 0)
+			goto stop;
+		asleep(50);
+	}
+	return -1;
+stop:
+	if((a->task & (ASdrq|ASbsy)) == 0){
+		*p |= Ast;
+		return 0;
+	}
+
+	*p |= Aclo;
+	for(i = 0; i < 500; i += 50){
+		if((*p & Aclo) == 0)
+			goto stop1;
+		asleep(50);
+	}
+	return -1;
+stop1:
+	/* extra check */
+	dprint("clo clear %x\n", a->task);
+	if(a->task & ASbsy)
+		return -1;
+	*p |= Ast;
+	return 0;
+}
+
+static int
+ahcicomreset(Aportc *pc)
+{
+	Actab *t;
+	Alist *l;
+	uchar *c;
+
+	dprint("ahcicomreset\n");
+	dreg("comreset ", pc->p);
+	if(ahciquiet(pc->p) == -1){
+		dprint("ahciquiet fails\n");
+		return -1;
+	}
+	dreg("comreset ", pc->p);
+
+	t = pc->m->ctab;
+	c = t->cfis;
+
+	memset(c, 0, 0x20);
+	c[0] = 0x27;
+	c[1] = 0x00;
+	c[7] = 0xa0;		/* obsolete device bits */
+	c[15] = 1<<2;		/* srst */
+
+	l = pc->m->list;
+	l->flags = Lclear | Lreset | 0x5;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	if(ahciwait(pc, 500) == -1){
+		dprint("first command in comreset fails\n");
+		return -1;
+	}
+	microdelay(250);
+	dreg("comreset ", pc->p);
+
+	memset(c, 0, 0x20);
+	c[0] = 0x27;
+	c[1] = 0x00;
+	c[7] = 0xa0;		/* obsolete device bits */
+
+	l = pc->m->list;
+	l->flags = Lwrite | 0x5;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	if(ahciwait(pc, 150) == -1){
+		dprint("second command in comreset fails\n");
+		return -1;
+	}
+	dreg("comreset ", pc->p);
+	return 0;
+}
+
+static int
+ahciidle(Aport *port)
+{
+	u32int *p, i, r;
+
+	p = &port->cmd;
+	if((*p&Arun) == 0)
+		return 0;
+	*p &= ~Ast;
+	r = 0;
+	for(i = 0; i < 500; i += 25){
+		if((*p & Acr) == 0)
+			goto stop;
+		asleep(25);
+	}
+	r = -1;
+stop:
+	if((*p & Afre) == 0)
+		return r;
+	*p &= ~Afre;
+	for(i = 0; i < 500; i += 25){
+		if((*p & Afre) == 0)
+			return 0;
+		asleep(25);
+	}
+	return -1;
+}
+
+/*
+ * § 6.2.2.1  first part; comreset handled by reset disk.
+ *	- remainder is handled by configdisk.
+ *	- ahcirecover is a quick recovery from a failed command.
+ */
+int
+ahciswreset(Aportc *pc)
+{
+	int i;
+
+	i = ahciidle(pc->p);
+	pc->p->cmd |= Afre;
+	if(i == -1)
+		return -1;
+	if(pc->p->task & (ASdrq|ASbsy))
+		return -1;
+	return 0;
+}
+
+int
+ahcirecover(Aportc *pc)
+{
+	ahciswreset(pc);
+	pc->p->cmd |= Ast;
+	if(setudmamode(pc, 5) == -1)
+		return -1;
+	return 0;
+}
+
+static void*
+malign(int size, int align)
+{
+	void *v;
+
+	v = xspanalloc(size, align, 0);
+	memset(v, 0, size);
+	return v;
+}
+
+static void
+setupfis(Afis *f)
+{
+	f->base = malign(0x100, 0x100);
+	f->d = f->base + 0;
+	f->p = f->base + 0x20;
+	f->r = f->base + 0x40;
+	f->u = f->base + 0x60;
+	f->devicebits = (u32int*)(f->base + 0x58);
+}
+
+static int
+ahciconfigdrive(Ahba *h, Aportc *c, int mode)
+{
+	Aportm *m;
+	Aport *p;
+
+	p = c->p;
+	m = c->m;
+
+	if(m->list == 0){
+		setupfis(&m->fis);
+		m->list = malign(sizeof *m->list, 1024);
+		m->ctab = malign(sizeof *m->ctab, 128);
+	}
+
+	if(p->sstatus & 3 && h->cap & Hsss){
+		dprint("configdrive:  spinning up ... [%ux]\n", p->sstatus);
+		p->cmd |= Apod | Asud;
+		asleep(1400);
+	}
+
+	p->serror = SerrAll;
+
+	p->list = PCIWADDR(m->list);
+	p->listhi = 0;
+	p->fis = PCIWADDR(m->fis.base);
+	p->fishi = 0;
+	p->cmd |= Afre | Ast;
+
+	/* disable power managment sequence from book. */
+	p->sctl = (3*Aipm) | (mode*Aspd) | 0*Adet;
+	p->cmd &= ~Aalpe;
+
+	p->ie = IEM;
+	return 0;
+}
+
+static int
+ahcienable(Ahba *h)
+{
+	h->ghc |= Hie;
+	return 0;
+}
+
+static int
+ahcidisable(Ahba *h)
+{
+	h->ghc &= ~Hie;
+	return 0;
+}
+
+static int
+countbits(ulong u)
+{
+	int i, n;
+
+	n = 0;
+	for(i = 0; i < 32; i++)
+		if(u & (1<<i))
+			n++;
+	return n;
+}
+
+static int
+ahciconf(Ctlr *c)
+{
+	Ahba *h;
+	u32int u;
+
+	h = c->hba = (Ahba*)c->mmio;
+	u = h->cap;
+
+	if((u&Hsam) == 0)
+		h->ghc |= Hae;
+
+	print("ahci hba sss %d; ncs %d; coal %d; mports %d; led %d; clo %d; ems %d;\n",
+		(u>>27) & 1, (u>>8) & 0x1f, (u>>7) & 1, u & 0x1f, (u>>25) & 1,
+		(u>>24) & 1, (u>>6) & 1);
+	return countbits(h->pi);
+}
+
+static int
+ahcihbareset(Ahba *h)
+{
+	int wait;
+
+	h->ghc |= 1;
+	for(wait = 0; wait < 1000; wait += 100){
+		if(h->ghc == 0)
+			return 0;
+		delay(100);
+	}
+	return -1;
+}
+
+static void
+idmove(char *p, ushort *a, int n)
+{
+	int i;
+	char *op, *e;
+
+	op = p;
+	for(i = 0; i < n/2; i++){
+		*p++ = a[i] >> 8;
+		*p++ = a[i];
+	}
+	*p = 0;
+	while(p > op && *--p == ' ')
+		*p = 0;
+	e = p;
+	p = op;
+	while(*p == ' ')
+		p++;
+	memmove(op, p, n - (e - p));
+}
+
+static int
+identify(Drive *d)
+{
+	u16int *id;
+	vlong osectors, s;
+	uchar oserial[21];
+	SDunit *u;
+
+	id = d->info;
+	s = ahciidentify(&d->portc, id);
+	if(s == -1){
+		d->state = Derror;
+		return -1;
+	}
+	osectors = d->sectors;
+	memmove(oserial, d->serial, sizeof d->serial);
+
+	d->sectors = s;
+	d->smartrs = 0;
+
+	idmove(d->serial, id + 10, 20);
+	idmove(d->firmware, id + 23, 8);
+	idmove(d->model, id + 27, 40);
+
+	u = d->unit;
+	memset(u->inquiry, 0, sizeof u->inquiry);
+	u->inquiry[2] = 2;
+	u->inquiry[3] = 2;
+	u->inquiry[4] = sizeof u->inquiry-4;
+	memmove(u->inquiry+8, d->model, 40);
+
+	if ((osectors == 0 || osectors != s) &&
+	    memcmp(oserial, d->serial, sizeof oserial) != 0){
+		d->mediachange = 1;
+		u->sectors = 0;
+	}
+	return 0;
+}
+
+static void
+clearci(Aport *p)
+{
+	if((p->cmd & Ast) == 0)
+		return;
+	p->cmd &= ~Ast;
+	p->cmd |=  Ast;
+}
+
+static void
+updatedrive(Drive *d)
+{
+	u32int cause, serr, s0, pr, ewake;
+	char *name;
+	Aport *p;
+	static u32int last;
+
+	pr = 1;
+	ewake = 0;
+	p = d->port;
+	cause = p->isr;
+	serr = p->serror;
+	p->isr = cause;
+	name = "??";
+	if(d->unit && d->unit->name)
+		name = d->unit->name;
+
+	if(p->ci == 0){
+		d->portm.flag |= Fdone;
+		wakeup(&d->portm);
+		pr = 0;
+	}else if(cause&Adps)
+		pr = 0;
+	if(cause&Ifatal){
+		ewake = 1;
+		dprint("Fatal\n");
+	}
+	if(cause&Adhrs){
+		if(p->task&33){
+			dprint("Adhrs cause = %ux; serr = %ux; task=%ux\n",
+				cause, serr, p->task);
+			d->portm.flag |= Ferror;
+			ewake = 1;
+		}
+		pr = 0;
+	}
+//	if(p->task & 1 && last != cause)
+//		dprint("err ca %ux serr %ux task %ux sstat %ux\n",
+//			cause, serr, p->task, p->sstatus);
+
+	if(pr)
+		dprint("%s: upd %ux ta %ux\n", name, cause, p->task);
+	if(cause & (Aprcs|Aifs)){
+		s0 = d->state;
+		switch(p->sstatus & 7){
+		case 0:
+			d->state = Dmissing;
+			break;
+		case 1:
+			d->state = Derror;
+			break;
+		case 3:
+			/* power mgnt crap for suprise removal */
+			p->ie |= Aprcs | Apcs;	/* is this required? */
+			d->state = Dreset;
+			break;
+		case 4:
+			d->state = Doffline;
+			break;
+		}
+		dprint("%s: %s → %s [Apcrs] %ux\n", name, diskstates[s0],
+			diskstates[d->state], p->sstatus);
+		/* print pulled message here. */
+		if(d->state != Dready)
+			d->portm.flag |= Ferror;
+		ewake = 1;
+	}
+	p->serror = serr;
+	if(ewake){
+		clearci(p);
+		wakeup(&d->portm);
+	}
+	last = cause;
+}
+
+static void
+pstatus(Drive *d, ulong s)
+{
+	/*
+	 * bogus code because the first interrupt is currently dropped.
+	 * likely my fault.  serror is may be cleared at the wrong time.
+	 */
+	switch(s){
+	case 0:
+		d->state = Dmissing;
+		break;
+	case 2:			/* should this be missing?  need testcase. */
+		dprint("pstatus 2\n");
+		/* FALLTHROUGH */
+	case 3:
+		d->wait = 0;
+		d->state = Dnew;
+		break;
+	case 4:
+		d->state = Doffline;
+		break;
+	}
+}
+
+static int
+configdrive(Drive *d)
+{
+	if(ahciconfigdrive(d->ctlr->hba, &d->portc, d->mode) == -1)
+		return -1;
+	ilock(d);
+	pstatus(d, d->port->sstatus & 7);
+	iunlock(d);
+	return 0;
+}
+
+static void
+resetdisk(Drive *d)
+{
+	uint state, det, stat;
+	Aport *p;
+
+	p = d->port;
+	det = p->sctl & 7;
+	stat = p->sstatus & 7;
+	state = (p->cmd >> 28) & 0xf;
+	dprint("resetdisk: icc %ux  det %d sdet %d\n", state, det, stat);
+	if(stat != 3){
+		ilock(d);
+		d->state = Dportreset;
+		iunlock(d);
+		return;
+	}
+	ilock(d);
+	state = d->state;
+	if(d->state != Dready || d->state != Dnew)
+		d->portm.flag |= Ferror;
+	clearci(p);			/* satisfy sleep condition */
+	wakeup(&d->portm);
+	iunlock(d);
+
+	qlock(&d->portm);
+
+	if(p->cmd & Ast && ahciswreset(&d->portc) == -1){
+		ilock(d);
+		d->state = Dportreset;	/* get a bigger stick */
+		iunlock(d);
+	} else {
+		ilock(d);
+		d->state = Dmissing;
+		iunlock(d);
+
+		configdrive(d);
+	}
+	dprint("resetdisk: %s → %s\n", diskstates[state], diskstates[d->state]);
+	qunlock(&d->portm);
+}
+
+static int
+newdrive(Drive *d)
+{
+	char *name, *s;
+	Aportc *c;
+	Aportm *m;
+
+	c = &d->portc;
+	m = &d->portm;
+
+	name = d->unit->name;
+	if(name == 0)
+		name = "??";
+
+	if(d->port->task == 0x80)
+		return -1;
+	qlock(c->m);
+	if(setudmamode(c, 5) == -1){
+		dprint("%s: can't set udma mode\n", name);
+		goto loose;
+	}
+	if(identify(d) == -1){
+		dprint("%s: identify failure\n", name);
+		goto loose;
+	}
+	if(m->feat &Dpower && setfeatures(c, 0x85) == -1){
+		m->feat &= ~Dpower;
+		if(ahcirecover(c) == -1)
+			goto loose;
+	}
+
+	ilock(d);
+	d->state = Dready;
+	iunlock(d);
+
+	qunlock(c->m);
+
+	s = "";
+	if(m->feat & Dllba)
+		s = "L";
+	idprint("%s: %sLBA %,lld sectors\n", d->unit->name, s, d->sectors);
+	idprint("  %s %s %s %s\n", d->model, d->firmware, d->serial,
+		d->mediachange?"[mediachange]":"");
+	return 0;
+loose:
+	qunlock(&d->portm);
+	return -1;
+}
+
+enum{
+	Nms		= 256,
+	Mphywait	=  2*1024/Nms - 1,
+	Midwait		= 16*1024/Nms - 1,
+	Mcomrwait	= 64*1024/Nms - 1,
+};
+
+static void
+westerndigitalhung(Drive *d)
+{
+	if ((d->portm.feat & Datapi) == 0 && d->active &&
+	    TK2MS(MACHP(0)->ticks-d->intick) > 5000){
+		dprint("%s: drive hung; resetting [%ux] ci=%x\n",
+			d->unit->name, d->port->task, d->port->ci);
+		d->state = Dreset;
+	}
+}
+
+static ushort olds[NCtlr*NCtlrdrv];
+
+static int
+doportreset(Drive *d)
+{
+	int i;
+
+	i = -1;
+	qlock(&d->portm);
+	if(ahciportreset(&d->portc) == -1)
+		dprint("ahciportreset fails\n");
+	else
+		i = 0;
+	qunlock(&d->portm);
+	dprint("portreset → %s  [task %ux]\n", diskstates[d->state],
+		d->port->task);
+	return i;
+}
+
+static void
+checkdrive(Drive *d, int i)
+{
+	ushort s;
+	char *name;
+
+	ilock(d);
+	name = d->unit->name;
+	s = d->port->sstatus;
+	if(s != olds[i]){
+		dprint("%s: status: %04ux -> %04ux: %s\n", name, olds[i], s,
+			diskstates[d->state]);
+		olds[i] = s;
+		d->wait = 0;
+	}
+	westerndigitalhung(d);
+	switch(d->state){
+	case Dnull:
+		break;
+	case Dmissing:
+	case Dnew:
+		switch(s & 0x107){
+		case 0:
+		case 1:
+			break;
+		default:
+			dprint("%s: unknown status %04ux\n", name, s);
+		case 0x100:
+			if(++d->wait & Mphywait)
+				break;
+reset:
+			if(++d->mode > DMsataii)
+				d->mode = 0;
+			if(d->mode == DMsatai){	/* we tried everything */
+				d->state = Dportreset;
+				goto portreset;
+			}
+			dprint("%s: reset; new mode %s\n", name,
+				modename[d->mode]);
+			iunlock(d);
+			resetdisk(d);
+			ilock(d);
+			break;
+		case 0x103:
+			if((++d->wait & Midwait) == 0){
+				dprint("%s: slow reset %04ux task=%ux; %d\n",
+					name, s, d->port->task, d->wait);
+				goto reset;
+			}
+			s = d->port->task & 0xff;
+			if(s == 0x7f || (s & ~0x17) != (1<<6))
+				break;
+			iunlock(d);
+			newdrive(d);
+			ilock(d);
+		}
+		break;
+	case Dready:
+		break;
+	case Doffline:
+		if(d->wait++ & Mcomrwait)
+			break;
+	case Derror:
+	case Dreset:
+		dprint("%s: reset [%s]: mode %d; status %04ux\n", name,
+			diskstates[d->state], d->mode, s);
+		iunlock(d);
+		resetdisk(d);
+		ilock(d);
+		break;
+	case Dportreset:
+portreset:
+		dprint("%s: portreset [%s]: mode %d; status %04ux\n", name, 
+			diskstates[d->state], d->mode, s);
+		d->portm.flag |= Ferror;
+		clearci(d->port);
+		wakeup(&d->portm);
+		if((s & 7) == 0){
+			d->state = Dmissing;
+			break;
+		}
+		iunlock(d);
+		doportreset(d);
+		ilock(d);
+		break;
+	}
+	iunlock(d);
+}
+
+static void
+satakproc(void*)
+{
+	int i;
+
+	memset(olds, 0xff, sizeof olds);
+	for (; ; ){
+		tsleep(&up->sleep, return0, 0, Nms);
+		for(i = 0; i < niadrive; i++)
+			checkdrive(iadrive[i], i);
+	}
+}
+
+static void
+iainterrupt(Ureg*, void *a)
+{
+	int i;
+	ulong cause, m;
+	Ctlr *c;
+	Drive *d;
+
+	c = a;
+	ilock(c);
+	cause = c->hba->isr;
+	for(i = 0; i < c->ndrive; i++){
+		m = 1<<i;
+		if((cause & m) == 0)
+			continue;
+		d = c->rawdrive+i;
+		ilock(d);
+		if(d->port->isr && c->hba->pi & m)
+			updatedrive(d);
+		c->hba->isr = m;
+		iunlock(d);
+	}
+	iunlock(c);
+}
+
+static int
+iaverify(SDunit *u)
+{
+	Ctlr *c;
+	Drive *d;
+
+	c = u->dev->ctlr;
+	d = c->drive[u->subno];
+	ilock(c);
+	ilock(d);
+	d->unit = u;
+	iunlock(d);
+	iunlock(c);
+	return 1;
+}
+
+static int
+iaenable(SDev *s)
+{
+	char name[32];
+	Ctlr *c;
+	static int once;
+
+	c = s->ctlr;
+	ilock(c);
+	if(!c->enabled) {
+		if(once++ == 0)
+			kproc("iasata", satakproc, 0);
+		pcisetbme(c->pci);
+		snprint(name, sizeof name, "%s (%s)", s->name, s->ifc->name);
+		intrenable(c->irq, iainterrupt, c, c->tbdf, name);
+		/* supposed to squelch leftover interrupts here. */
+		ahcienable(c->hba);
+	}
+	c->enabled = 1;
+	iunlock(c);
+	return 1;
+}
+
+static int
+iadisable(SDev *s)
+{
+	char name[32];
+	Ctlr *c;
+
+	c = s->ctlr;
+	ilock(c);
+	ahcidisable(c->hba);
+	snprint(name, sizeof name, "%s (%s)", s->name, s->ifc->name);
+	intrdisable(c->irq, iainterrupt, c, c->tbdf, name);
+	c->enabled = 0;
+	iunlock(c);
+	return 1;
+}
+
+static int
+iaonline(SDunit *unit)
+{
+	ulong r;
+	Ctlr *c;
+	Drive *d;
+
+	c = unit->dev->ctlr;
+	d = c->drive[unit->subno];
+	r = 0;
+
+	if((d->portm.feat & Datapi) && d->mediachange){
+		r = scsionline(unit);
+		if(r > 0)
+			d->mediachange = 0;
+		return r;
+	}
+
+	ilock(d);
+	if(d->mediachange){
+		r = 2;
+		d->mediachange = 0;
+		/* devsd resets this after online is called; why? */
+		unit->sectors = d->sectors;
+		unit->secsize = 512;
+	} else if(d->state == Dready)
+		r = 1;
+	iunlock(d);
+
+	return r;
+}
+
+/* returns locked list! */
+static Alist*
+ahcibuild(Aportm *m, uchar *cmd, void *data, int n, vlong lba)
+{
+	uchar *c, acmd, dir, llba;
+	Actab *t;
+	Alist *l;
+	Aprdt *p;
+	static uchar tab[2][2] = {0xc8, 0x25, 0xca, 0x35};
+
+	dir = *cmd != 0x28;
+	llba = m->feat & Dllba? 1: 0;
+	acmd = tab[dir][llba];
+
+	qlock(m);
+	l = m->list;
+	t = m->ctab;
+	c = t->cfis;
+
+	c[0] = 0x27;
+	c[1] = 0x80;
+	c[2] = acmd;
+	c[3] = 0;
+
+	c[4] = lba;		/* sector		lba low	7:0 */
+	c[5] = lba >> 8;	/* cylinder low		lba mid	15:8 */
+	c[6] = lba >> 16;	/* cylinder hi		lba hi	23:16 */
+	c[7] = 0xa0 | 0x40;	/* obsolete device bits + lba */
+	if(llba == 0)
+		c[7] |= (lba >> 24) & 7;
+
+	c[8]  = lba >> 24;	/* sector (exp)		lba 	31:24 */
+	c[9]  = lba >> 32;	/* cylinder low (exp)	lba	39:32 */
+	c[10] = lba >> 48;	/* cylinder hi (exp)	lba	48:40 */
+	c[11] = 0;		/* features (exp); */
+
+	c[12] = n;		/* sector count */
+	c[13] = n >> 8;		/* sector count (exp) */
+	c[14] = 0;		/* r */
+	c[15] = 0;		/* control */
+
+	*(ulong*)(c + 16) = 0;
+
+	l->flags = 1<<16 | Lpref | 0x5;	/* Lpref ?? */
+	if(dir == Write)
+		l->flags |= Lwrite;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	p = &t->prdt;
+	p->dba = PCIWADDR(data);
+	p->dbahi = 0;
+	p->count = 1<<31 | (512*n - 2) | 1;
+
+	return l;
+}
+
+static Alist*
+ahcibuildpkt(Aportm *m, SDreq *r, void *data, int n)
+{
+	int fill, len;
+	uchar *c;
+	Actab *t;
+	Alist *l;
+	Aprdt *p;
+
+	qlock(m);
+	l = m->list;
+	t = m->ctab;
+	c = t->cfis;
+
+	fill = m->feat & Datapi16? 16: 12;
+	if((len = r->clen) > fill)
+		len = fill;
+	memmove(t->atapi, r->cmd, len);
+	memset(t->atapi+len, 0, fill-len);
+
+	c[0] = 0x27;
+	c[1] = 0x80;
+	c[2] = 0xa0;
+	if(n != 0)
+		c[3] = 1;		/* dma */
+	else
+		c[3] = 0;		/* features (exp); */
+
+	c[4] = 0;		/* sector		lba low	7:0 */
+	c[5] = n;		/* cylinder low		lba mid	15:8 */
+	c[6] = n >> 8;		/* cylinder hi		lba hi	23:16 */
+	c[7] = 0xa0;		/* obsolete device bits */
+
+	*(ulong*)(c + 8) = 0;
+//	c[8] =  lba >> 24;	/* sector (exp)		lba 	31:24 */
+//	c[9] =  lba >> 32;	/* cylinder low (exp)	lba	39:32 */
+//	c[10] = lba >> 48;	/* cylinder hi (exp)	lba	48:40 */
+//	c[11] = 0;
+
+	*(ulong*)(c + 12) = 0;
+	*(ulong*)(c + 16) = 0;
+
+	l->flags = 1<<16 | Lpref | Latapi | 0x5;
+	if(r->write != 0)
+		l->flags |= Lwrite;
+	l->len = 0;
+	l->ctab = PCIWADDR(t);
+	l->ctabhi = 0;
+
+	p = &t->prdt;
+	p->dba = PCIWADDR(data);
+	p->dbahi = 0;
+	p->count = 1<<31 | (n-2) | 1;
+
+	return l;
+}
+
+static int
+waitready(Drive *d)
+{
+	u32int s, t, i;
+
+	for(i = 0; i < 120; i++){
+		ilock(d);
+		s = d->port->sstatus;
+		t = d->port->task;
+		iunlock(d);
+		if((s & 0x100) == 0)
+			return -1;
+		if(d->state == Dready && (s & 7) == 3)
+			return 0;
+		if((i+1) % 30 == 0)
+			print("%s: waitready: [%s] task=%ux sstat=%ux\n",
+				d->unit->name, diskstates[d->state], t, s);
+		esleep(1000);
+	}
+	print("%s: not responding; offline\n", d->unit->name);
+	ilock(d);
+	d->state = Doffline;
+	iunlock(d);
+	return -1;
+}
+
+static int
+iariopkt(SDreq *r, Drive *d)
+{
+	int n, count, try, max, flag, task;
+	char *name;
+	uchar *cmd, *data;
+	Aport *p;
+	Asleep as;
+
+	cmd = r->cmd;
+	name = d->unit->name;
+	p = d->port;
+
+	aprint("%02ux %02ux\n", cmd[0], cmd[2]);
+	if(cmd[0] == 0x5a && (cmd[2] & 0x3f) == 0x3f)
+		return sdmodesense(r, cmd, d->info, sizeof d->info);
+	r->rlen = 0;
+	count = r->dlen;
+	max = 65536;
+
+	try = 0;
+retry:
+	if(waitready(d) == -1)
+		return SDeio;
+	data = r->data;
+	n = count;
+	if(n > max)
+		n = max;
+	d->active++;
+	ahcibuildpkt(&d->portm, r, data, n);
+	ilock(d);
+	d->portm.flag = 0;
+	iunlock(d);
+	p->ci = 1;
+
+	as.p = p;
+	as.i = 1;
+	d->intick = MACHP(0)->ticks;
+
+	while(waserror())
+		;
+	sleep(&d->portm, ahciclear, &as);
+	poperror();
+
+	ilock(d);
+	flag = d->portm.flag;
+	task = d->port->task;
+	iunlock(d);
+
+	if(task & (Efatal<<8) || task & (ASbsy|ASdrq) && d->state == Dready){
+		d->port->ci = 0;		/* @? */
+		ahcirecover(&d->portc);
+		task = d->port->task;
+	}
+	d->active--;
+	qunlock(&d->portm);
+	if(flag == 0){
+		if(++try == 10){
+			print("%s: bad disk\n", name);
+			r->status = SDcheck;
+			return SDcheck;
+		}
+		iprint("%s: retry\n", name);
+		esleep(1000);
+		goto retry;
+	}
+	if(flag&Ferror){
+		iprint("%s: i/o error %ux\n", name, task);
+		r->status = SDcheck;
+		return SDcheck;
+	}
+
+	data += n;
+
+	r->rlen = data - (uchar*)r->data;
+	r->status = SDok;
+	return SDok;
+}
+
+static int
+iario(SDreq *r)
+{
+	int i, n, count, try, max, flag, task;
+	vlong lba;
+	char *name;
+	uchar *cmd, *data;
+	Aport *p;
+	Asleep as;
+	Ctlr *c;
+	Drive *d;
+	SDunit *unit;
+
+	unit = r->unit;
+	c = unit->dev->ctlr;
+	d = c->drive[unit->subno];
+	if(d->portm.feat & Datapi)
+		return iariopkt(r, d);
+	cmd = r->cmd;
+	name = d->unit->name;
+	p = d->port;
+
+	if(r->cmd[0] == 0x35){
+		qlock(&d->portm);
+		i = flushcache(&d->portc);
+		qunlock(&d->portm);
+		if(i == 0)
+			return sdsetsense(r, SDok, 0, 0, 0);
+		return sdsetsense(r, SDcheck, 3, 0xc, 2);
+	}
+
+	if((i = sdfakescsi(r, d->info, sizeof d->info)) != SDnostatus){
+		r->status = i;
+		return i;
+	}
+
+	if(*cmd != 0x28 && *cmd != 0x2a){
+		print("%s: bad cmd 0x%.2ux\n", name, cmd[0]);
+		r->status = SDcheck;
+		return SDcheck;
+	}
+
+	lba =   cmd[2]<<24 | cmd[3]<<16 | cmd[4]<<8 | cmd[5];
+	count = cmd[7]<<8  | cmd[8];
+	if(r->data == nil)
+		return SDok;
+	if(r->dlen < count*unit->secsize)
+		count = r->dlen/unit->secsize;
+	max = 128;
+
+	try = 0;
+retry:
+	if(waitready(d) == -1)
+		return SDeio;
+	data = r->data;
+	while(count > 0){
+		n = count;
+		if(n > max)
+			n = max;
+		d->active++;
+		ahcibuild(&d->portm, cmd, data, n, lba);
+		ilock(d);
+		d->portm.flag = 0;
+		iunlock(d);
+		p->ci = 1;
+
+		as.p = p;
+		as.i = 1;
+		d->intick = MACHP(0)->ticks;
+
+		while(waserror())
+			;
+		sleep(&d->portm, ahciclear, &as);
+		poperror();
+
+		ilock(d);
+		flag = d->portm.flag;
+		task = d->port->task;
+		iunlock(d);
+
+		if (task & (Efatal<<8) || task & (ASbsy|ASdrq) &&
+		    d->state == Dready){
+			d->port->ci = 0;	/* @? */
+			ahcirecover(&d->portc);
+			task = d->port->task;
+		}
+		d->active--;
+		qunlock(&d->portm);
+		if(flag == 0){
+			if(++try == 10){
+				print("%s: bad disk\n", name);
+				r->status = SDeio;
+				return SDeio;
+			}
+			iprint("%s: retry %lld\n", name, lba);
+			esleep(1000);
+			goto retry;
+		}
+		if(flag & Ferror){
+			iprint("%s: i/o error %ux @%,lld\n", name, task, lba);
+			r->status = SDeio;
+			return SDeio;
+		}
+
+		count -= n;
+		lba += n;
+		data += n * unit->secsize;
+	}
+	r->rlen = data - (uchar*)r->data;
+	r->status = SDok;
+	return SDok;
+}
+
+/*
+ * configure drives 0-5 as ahci sata  (c.f. errata)
+ */
+static int
+iaahcimode(Pcidev *p)
+{
+	dprint("iaahcimode %ux %ux %ux\n", pcicfgr8(p, 0x91), pcicfgr8(p, 92),
+		pcicfgr8(p, 93));
+	pcicfgw16(p, 0x92, pcicfgr32(p, 0x92) | 0xf);	/* ports 0-3 */
+//	pcicfgw8(p, 0x93,  pcicfgr32(p, 9x93) | 3);	/* ports 4-5 */
+	return 0;
+
+}
+
+static void
+iasetupahci(Ctlr *c)
+{
+	/* disable cmd block decoding. */
+	pcicfgw16(c->pci, 0x40, pcicfgr16(c->pci, 0x40) & ~(1<<15));
+	pcicfgw16(c->pci, 0x42, pcicfgr16(c->pci, 0x42) & ~(1<<15));
+
+	c->lmmio[0x4/4] |=  1<<31;	/* enable ahci mode (ghc register) */
+	c->lmmio[0xc/4]  = (1<<6)-1;	/* 5 ports (supposedly ro pi reg) */
+
+	/* enable ahci mode. */
+//	pcicfgw8(c->pci, 0x90, 0x40);
+	pcicfgw16(c->pci, 0x90, 1<<6 | 1<<5);	/* pedanticly proper for ich9 */
+}
+
+static SDev*
+iapnp(void)
+{
+	int i, n, nunit;
+	ulong io;
+	Ctlr *c;
+	Drive *d;
+	Pcidev *p;
+	SDev *head, *tail, *s;
+	static int done;
+
+	if(done++)
+		return nil;
+
+	p = nil;
+	head = nil;
+	tail = nil;
+loop:
+	while((p = pcimatch(p, 0x8086, 0)) != nil){
+		if ((p->did&0xfffc) != 0x2680 &&	/* esb */
+		    (p->did&0xfffe) != 0x27c4)		/* 82801g[bh]m */
+			continue;
+		if(niactlr == NCtlr){
+			print("iapnp: too many controllers\n");
+			break;
+		}
+		c = iactlr + niactlr;
+		s = sdevs  + niactlr;
+		memset(c, 0, sizeof *c);
+		memset(s, 0, sizeof *s);
+		io = p->mem[Abar].bar & ~0xf;
+		c->mmio = vmap(io, p->mem[0].size);
+		if(c->mmio == 0){
+			print("iapnp: address 0x%luX in use did=%x\n", io,
+				p->did);
+			continue;
+		}
+		c->lmmio = (ulong*)c->mmio;
+		c->pci = p;
+		if(p->did != 0x2681)
+			iasetupahci(c);
+		nunit = ahciconf(c);
+		/* ahcihbareset((Ahba*)c->mmio); */
+		if(iaahcimode(p) == -1)
+			break;
+		if(nunit < 1){
+			vunmap(c->mmio, p->mem[0].size);
+			continue;
+		}
+		i = (c->hba->cap >> 21) & 1;
+		print("intel 63[12]xesb: sata-%s ports with %d ports\n",
+			"I\0II" + i*2, nunit);
+		s->ifc = &sd63xxesbifc;
+		s->ctlr = c;
+		s->nunit = nunit;
+		s->idno = 'E';
+		c->sdev = s;
+		c->irq = p->intl;
+		c->tbdf = p->tbdf;
+		c->ndrive = nunit;
+
+		/* map the drives -- they don't all need to be enabled. */
+		memset(c->rawdrive, 0, sizeof c->rawdrive);
+		n = 0;
+		for(i = 0; i < NCtlrdrv; i++) {
+			d = c->rawdrive+i;
+			d->portno = i;
+			d->driveno = -1;
+			d->sectors = 0;
+			d->ctlr = c;
+			if((c->hba->pi & (1 << i)) == 0)
+				continue;
+			d->port = (Aport*)(c->mmio + 0x80*i + 0x100);
+			d->portc.p = d->port;
+			d->portc.m = &d->portm;
+			d->driveno = n++;
+			c->drive[i] = d;
+			iadrive[d->driveno] = d;
+		}
+		for(i = 0; i < n; i++)
+			if(ahciidle(c->drive[i]->port) == -1){
+				dprint("intel 63[12]xesb: port %d wedged; abort\n",
+					i);
+				goto loop;
+			}
+		for(i = 0; i < n; i++){
+			c->drive[i]->mode = DMsatai;
+			configdrive(c->drive[i]);
+		}
+
+		niadrive += nunit;
+		if(head)
+			tail->next = s;
+		else
+			head = s;
+		tail = s;
+	}
+	return head;
+}
+
+static char* smarttab[] = {
+	"unset",
+	"error",
+	"threshold exceeded",
+	"normal"
+};
+
+static char *
+pflag(char *s, char *e, uchar f)
+{
+	uchar i, m;
+
+	for(i = 0; i < 8; i++){
+		m = 1 << i;
+		if(f & m)
+			s = seprint(s, e, "%s ", flagname[i]);
+	}
+	return seprint(s, e, "\n");
+}
+
+static int
+iarctl(SDunit *u, char *p, int l)
+{
+	char *e, *op;
+	char buf[32];
+	Aport *o;
+	Ctlr *c;
+	Drive *d;
+
+	if((c = u->dev->ctlr) == nil)
+		return 0;
+	d = c->drive[u->subno];
+	o = d->port;
+
+	e = p+l;
+	op = p;
+	if(d->state == Dready){
+		p = seprint(p, e, "model\t%s\n", d->model);
+		p = seprint(p, e, "serial\t%s\n", d->serial);
+		p = seprint(p, e, "firm\t%s\n", d->firmware);
+		if(d->smartrs == 0xff)
+			p = seprint(p, e, "smart\tenable error\n");
+		else if(d->smartrs == 0)
+			p = seprint(p, e, "smart\tdisabled\n");
+		else
+			p = seprint(p, e, "smart\t%s\n",
+				smarttab[d->portm.smart]);
+		p = seprint(p, e, "flag\t");
+		p = pflag(p, e, d->portm.feat);
+	}else
+		p = seprint(p, e, "no disk present [%s]\n", diskstates[d->state]);
+	serrstr(o->serror, buf, buf + sizeof buf - 1);
+	p = seprint(p, e, "reg\ttask %ux cmd %ux serr %ux %s ci %ux is %ux; sig %ux\n",
+		o->task, o->cmd, o->serror, buf, o->ci, o->isr, o->sig);
+	p = seprint(p, e, "geometry %llud 512\n", d->sectors);
+
+	return p-op;
+}
+
+static void
+runflushcache(Drive *d)
+{
+	long t0;
+
+	t0 = MACHP(0)->ticks;
+	qlock(&d->portm);
+	flushcache(&d->portc);
+	qunlock(&d->portm);
+	dprint("flush in %ldms\n", TK2MS(MACHP(0)->ticks - t0));
+}
+
+static void
+forcemode(Drive *d, char *mode)
+{
+	int i;
+
+	for(i = 0; i < nelem(modename); i++)
+		if(strcmp(mode, modename[i]) == 0)
+			break;
+	if(i == nelem(modename))
+		i = 0;
+	ilock(d);
+	d->mode = i;
+	iunlock(d);
+}
+
+static void
+runsmartable(Drive *d, int i)
+{
+	if(waserror()){
+		qunlock(&d->portm);
+		d->smartrs = 0;
+		nexterror();
+	}
+	qlock(&d->portm);
+	d->smartrs = smart(&d->portc, i);
+	d->portm.smart = 0;
+	qunlock(&d->portm);
+	poperror();
+}
+
+static void
+forcestate(Drive *d, char *state)
+{
+	int i;
+
+	for(i = 0; i < nelem(diskstates); i++)
+		if(strcmp(state, diskstates[i]) == 0)
+			break;
+	if(i == nelem(diskstates))
+		i = 0;
+	ilock(d);
+	d->state = i;
+	if(i == Dnull){
+		d->mediachange = 1;
+		d->unit->sectors = 0;	/* force disk to disappear */
+	}
+	iunlock(d);
+}
+
+static int
+iawctl(SDunit *u, Cmdbuf *cmd)
+{
+	char **f;
+	Ctlr *c;
+	Drive *d;
+
+	c = u->dev->ctlr;
+	d = c->drive[u->subno];
+	f = cmd->f;
+
+	if(strcmp(f[0], "flushcache") == 0)
+		runflushcache(d);
+	else if(strcmp(f[0], "identify") ==  0){
+		uint i;
+
+		i = strtoul(f[1]? f[1]: "0", 0, 0);
+		if(i > 0xff)
+			i = 0;
+		dprint("%04d %ux\n", i, d->info[i]);
+	}else if(strcmp(f[0], "mode") == 0)
+		forcemode(d, f[1]? f[1]: "satai");
+	else if(strcmp(f[0], "nop") == 0){
+		if((d->portm.feat & Dnop) == 0){
+			cmderror(cmd, "nop command not supported");
+			return -1;
+		}
+		if(waserror()){
+			qunlock(&d->portm);
+			nexterror();
+		}
+		qlock(&d->portm);
+		nop(&d->portc);
+		qunlock(&d->portm);
+		poperror();
+	}else if(strcmp(f[0], "reset") == 0)
+		forcestate(d, "reset");
+	else if(strcmp(f[0], "smart") == 0){
+		if(d->smartrs == 0){
+			cmderror(cmd, "smart not enabled");
+			return -1;
+		}
+		if(waserror()){
+			qunlock(&d->portm);
+			d->smartrs = 0;
+			nexterror();
+		}
+		qlock(&d->portm);
+		d->portm.smart = 2 + smartrs(&d->portc);
+		qunlock(&d->portm);
+		poperror();
+	}else if(strcmp(f[0], "smartdisable") == 0)
+		runsmartable(d, 1);
+	else if(strcmp(f[0], "smartenable") == 0)
+		runsmartable(d, 0);
+	else if(strcmp(f[0], "state") == 0)
+		forcestate(d, f[1]? f[1]: "null");
+	else{
+		cmderror(cmd, Ebadctl);
+		return -1;
+	}
+	return 0;
+}
+
+static char *
+portr(char *p, char *e, uint x)
+{
+	int i, a;
+
+	p[0] = 0;
+	a = -1;
+	for(i = 0; i < 32; i++){
+		if((x & (1 << i)) == 0){
+			if(a != -1 && i - 1 != a)
+				p = seprint(p, e, "-%d", i - 1);
+			a = -1;
+			continue;
+		}
+		if(a == -1){
+			if(i > 0)
+				p = seprint(p, e, ", ");
+			p = seprint(p, e, "%d", a = i);
+		}
+	}
+	if(a != -1 && i - 1 != a)
+		p = seprint(p, e, "-%d", i - 1);
+	return p;
+}
+
+#define has(x, s) if(u & (x)) p = seprint(p, e, (s))
+
+static char*
+iartopctl(SDev *s, char *p, char *e)
+{
+	u32int u;
+	char name[10], pr[25];
+	Ahba *h;
+	Ctlr *c;
+
+	c = s->ctlr;
+
+	snprint(name, sizeof name, "sd%c", s->idno);
+	p = seprint(p, e, "%s ahci ", name);
+	u = c->hba->cap;
+	has(Hs64a, "64a ");
+	has(Hsncq, "ncq ");
+	has(Hssntf, "ntf ");
+	has(Hsmps, "mps ");
+	has(Hsss, "ss ");
+	has(Hsalp, "alp ");
+	has(Hsal, "led ");
+	has(Hsclo, "clo ");
+	has(Hsam, "am ");
+	has(Hspm, "pm ");
+	has(Hssc, "slum ");
+	has(Hpsc, "pslum ");
+	has(Hcccs, "coal ");
+	has(Hems, "ems ");
+	has(Hsxs, "sxs ");
+	p = seprint(p, e, "\n");
+
+	p = seprint(p, e, "%s iss %d ncs %d np %d\n", name, (u >> 20) & 0xf,
+		(u >> 8) & 0x1f, 1 + (u & 0x1f));
+	h = c->hba;
+	portr(pr, pr+sizeof pr, h->pi);
+	p = seprint(p, e, "%s ghc %ux isr %ux pi %ux %s ver %ux\n",
+		name, h->ghc, h->isr, h->pi, pr, h->ver);
+	return p;
+}
+
+static int
+iawtopctl(SDev *, Cmdbuf *cmd)
+{
+	char **f;
+	int *v;
+
+	f = cmd->f;
+	v = 0;
+
+	if(strcmp(f[0], "debug") == 0)
+		v = &debug;
+	else if(strcmp(f[0], "idprint") == 0)
+		v = &prid;
+	else if(strcmp(f[0], "aprint") == 0)
+		v = &datapi;
+	else
+		cmderror(cmd, Ebadctl);
+
+	switch(cmd->nf){
+	default:
+		cmderror(cmd, Ebadarg);
+	case 1:
+		*v ^= 1;
+		break;
+	case 2:
+		if(strcmp(f[1], "on") == 0)
+			*v = 1;
+		else
+			*v = 0;
+		break;
+	}
+	return 0;
+}
+
+SDifc sd63xxesbifc = {
+	"iahci",
+
+	iapnp,
+	nil,		/* legacy */
+	iaenable,
+	iadisable,
+
+	iaverify,
+	iaonline,
+	iario,
+	iarctl,
+	iawctl,
+
+	scsibio,
+	nil,		/* probe */
+	nil,		/* clear */
+	iartopctl,
+	iawtopctl,
+};

+ 4 - 4
sys/src/9/port/netif.c

@@ -558,7 +558,7 @@ matchtoken(char *p, char *token)
 }
 
 void
-hnputv(void *p, vlong v)
+hnputv(void *p, uvlong v)
 {
 	uchar *a;
 
@@ -568,7 +568,7 @@ hnputv(void *p, vlong v)
 }
 
 void
-hnputl(void *p, ulong v)
+hnputl(void *p, uint v)
 {
 	uchar *a;
 
@@ -589,7 +589,7 @@ hnputs(void *p, ushort v)
 	a[1] = v;
 }
 
-vlong
+uvlong
 nhgetv(void *p)
 {
 	uchar *a;
@@ -598,7 +598,7 @@ nhgetv(void *p)
 	return ((vlong)nhgetl(a) << 32) | nhgetl(a+4);
 }
 
-ulong
+uint
 nhgetl(void *p)
 {
 	uchar *a;

+ 4 - 4
sys/src/9/port/portfns.h

@@ -378,11 +378,11 @@ Segment*	data2txt(Segment*);
 Segment*	dupseg(Segment**, int, int);
 Segment*	newseg(int, ulong, ulong);
 Segment*	seg(Proc*, ulong, int);
-void		hnputv(void*, vlong);
-void		hnputl(void*, ulong);
+void		hnputv(void*, uvlong);
+void		hnputl(void*, uint);
 void		hnputs(void*, ushort);
-vlong		nhgetv(void*);
-ulong		nhgetl(void*);
+uvlong		nhgetv(void*);
+uint		nhgetl(void*);
 ushort		nhgets(void*);
 void		_xinc(long*);
 long		_xdec(long*);

+ 1 - 1
sys/src/cmd/auth/factotum/util.c

@@ -278,7 +278,7 @@ failure(Fsstate *s, char *fmt, ...)
 		snprint(e, sizeof e, fmt, arg);
 		va_end(arg);
 		strecpy(s->err, s->err+sizeof(s->err), e);
-		errstr(e, sizeof e);
+		werrstr(e);
 	}
 	flog("%d: failure %s", s->seqnum, s->err);
 	return RpcFailure;

+ 2 - 0
sys/src/cmd/ip/ppp/ppp.c

@@ -1024,6 +1024,8 @@ dropoption(Pstate *p, Lcpopt *o)
 	unsigned n = o->type;
 
 	switch(n){
+		case Oipaddr:
+			break;
 		case Oipdns:
 			p->optmask &= ~Fipdns;
 			break;

+ 15 - 10
sys/src/cmd/troff/n8.c

@@ -1,6 +1,7 @@
 #include "tdef.h"
 #include "fns.h"
 #include "ext.h"
+#include <assert.h>
 
 #define	HY_BIT	0200	/* stuff in here only works for 7-bit ascii */
 			/* this value is used (as a literal) in suftab.c */
@@ -10,7 +11,7 @@
 
 /*
  * troff8.c
- * 
+ *
  * hyphenation
  */
 
@@ -58,7 +59,7 @@ void hyphen(Tchar *wp)
 
 	/* this appears to sort hyphenation points into increasing order */
 	*hyp++ = 0;
-	if (*hyptr) 
+	if (*hyptr)
 		for (j = 1; j; ) {
 			j = 0;
 			for (hyp = hyptr + 1; *hyp != 0; hyp++) {
@@ -193,7 +194,7 @@ int exword(void)
 			return(0);
 		w = wdstart;
 		while (*e && w <= hyend && (*e & 0177) == maplow(cbits(*w))) {
-			e++; 
+			e++;
 			w++;
 		}
 		if (!*e) {
@@ -208,10 +209,10 @@ int exword(void)
 				}
 				return(1);
 			} else {
-				e++; 
+				e++;
 				continue;
 			}
-		} else 
+		} else
 			while (*e++)
 				;
 	}
@@ -248,7 +249,7 @@ again:
 	}
 	s = s0 + i - 1;
 	w = hyend;
-	if (*s0 & HY_BIT) 
+	if (*s0 & HY_BIT)
 		goto mark;
 	while (s > s0) {
 		w--;
@@ -272,7 +273,7 @@ mark:
 
 maplow(int i)
 {
-	if (isupper(i)) 
+	if (isupper(i))
 		i = tolower(i);
 	return(i);
 }
@@ -326,7 +327,7 @@ again:
 			val *= dilook('a', cbits(*w), bxh);
 		else if (w == wdstart + 1)
 			val *= dilook(cbits(*(w-1)), cbits(*w), bxxh);
-		else 
+		else
 			val *= dilook(cbits(*(w-1)), cbits(*w), xxh);
 		val *= dilook(cbits(*w), cbits(*(w+1)), xhx);
 		val *= dilook(cbits(*(w+1)), cbits(*(w+2)), hxx);
@@ -399,7 +400,7 @@ static int texit(Tchar *start, Tchar *end)	/* hyphenate as in tex, return # foun
 	for (i = 0; i <= nw; i++)
 		cnt[i] = '0';
 
-	for (wp = w; wp < w + nw; wp++) {
+	for (wp = w; wp+1 < w+nw; wp++) {
 		for (pp = trie[trieindex(*wp, *(wp+1))]; pp < nextpat; ) {
 			if (pp == 0		/* no trie entry */
 			 || *pp != *wp		/* no match on 1st letter */
@@ -536,5 +537,9 @@ static void fixup(void)	/* build indexes of where . a b c ... start */
 
 static int trieindex(int d1, int d2)
 {
-	return 27 * (d1 == '.' ? 0 : d1 - 'a' + 1) + (d2 == '.' ? 0 : d2 - 'a' + 1);
+	int i;
+
+	i = 27*(d1 == '.'? 0: d1 - 'a' + 1) + (d2 == '.'? 0: d2 - 'a' + 1);
+	assert(0 <= i && i < 27*27);
+	return i;
 }

+ 8 - 2
sys/src/cmd/usb/misc/usbmouse.c

@@ -1,3 +1,7 @@
+/*
+ * usbmouse - listen for usb mouse events and turn them into
+ *	writes on /dev/mousein.
+ */
 #include <u.h>
 #include <libc.h>
 #include <bio.h>
@@ -31,7 +35,7 @@ int
 robusthandler(void*, char *s)
 {
 	if (debug) fprint(2, "inthandler: %s\n", s);
-	return (s && (strstr(s, "interrupted")|| strstr(s, "hangup")));
+	return s && (strstr(s, "interrupted") || strstr(s, "hangup"));
 }
 
 long
@@ -140,7 +144,9 @@ threadmain(int argc, char *argv[])
 		ctlrno = atoi(argv[0]);
 		i = atoi(argv[1]);
 		ep = 1;			/* a guess */
-	found:
+		if (verbose)
+			fprint(2, "assuming endpoint %d\n", ep);
+found:
 		snprint(ctlfile, sizeof ctlfile, ctlfmt, ctlrno, i);
 		snprint(msefile, sizeof msefile, msefmt, ctlrno, i, ep);
 		break;