Browse Source

Plan 9 from Bell Labs 2006-04-14

David du Colombier 18 years ago
parent
commit
63aca9c8c1

+ 34 - 30
dist/replica/_plan9.db

@@ -7954,7 +7954,7 @@ sys/src/9/pc/devusb.c - 664 sys sys 1105193103 18364
 sys/src/9/pc/devvga.c - 664 sys sys 1131290315 9332
 sys/src/9/pc/dma.c - 664 sys sys 1142966373 5332
 sys/src/9/pc/ether2000.c - 664 sys sys 1089299187 4819
-sys/src/9/pc/ether2114x.c - 664 sys sys 1081706476 41545
+sys/src/9/pc/ether2114x.c - 664 sys sys 1144963814 41694
 sys/src/9/pc/ether589.c - 664 sys sys 1015014516 4644
 sys/src/9/pc/ether79c970.c - 664 sys sys 1131290338 13953
 sys/src/9/pc/ether8003.c - 664 sys sys 1015014516 6665
@@ -9003,14 +9003,15 @@ sys/src/boot/pc/boot.c - 664 sys sys 1130887226 8421
 sys/src/boot/pc/bootld.c - 664 sys sys 1015007948 1801
 sys/src/boot/pc/bootp.c - 664 sys sys 1114464742 12374
 sys/src/boot/pc/cga.c - 664 sys sys 1015007948 1362
+sys/src/boot/pc/cis.c - 664 sys sys 1144961189 9232
 sys/src/boot/pc/clock.c - 664 sys sys 1103641772 6425
 sys/src/boot/pc/conf.c - 664 sys sys 1094674484 10217
 sys/src/boot/pc/console.c - 664 sys sys 1094674483 3388
-sys/src/boot/pc/dat.h - 664 sys sys 1109364490 3565
+sys/src/boot/pc/dat.h - 664 sys sys 1144961189 3597
 sys/src/boot/pc/devfloppy.c - 664 sys sys 1032215913 15505
 sys/src/boot/pc/devfloppy.h - 664 sys sys 1032409559 4081
-sys/src/boot/pc/devi82365.c - 664 sys sys 1019533020 23202
-sys/src/boot/pc/devpccard.c - 664 sys sys 1140711214 41433
+sys/src/boot/pc/devi82365.c - 664 sys sys 1144961189 15051
+sys/src/boot/pc/devpccard.c - 664 sys sys 1144961189 33938
 sys/src/boot/pc/devsd.c - 664 sys sys 1077033681 11262
 sys/src/boot/pc/dma.c - 664 sys sys 1015007949 4972
 sys/src/boot/pc/dosboot.c - 664 sys sys 1097716791 11240
@@ -9019,30 +9020,30 @@ sys/src/boot/pc/eoffs - 664 sys sys 1015007950 0
 sys/src/boot/pc/error.h - 664 sys sys 1015007950 3081
 sys/src/boot/pc/ether.c - 664 sys sys 1112382847 5090
 sys/src/boot/pc/ether2000.c - 664 sys sys 1015007950 2609
-sys/src/boot/pc/ether2114x.c - 664 sys sys 1066618033 37048
-sys/src/boot/pc/ether589.c - 664 sys sys 1107921511 4620
+sys/src/boot/pc/ether2114x.c - 664 sys sys 1144977462 38028
+sys/src/boot/pc/ether589.c - 664 sys sys 1144961189 4624
 sys/src/boot/pc/ether79c970.c - 664 sys sys 1015007950 11717
 sys/src/boot/pc/ether8003.c - 664 sys sys 1015007950 6446
 sys/src/boot/pc/ether8139.c - 664 sys sys 1121393459 14823
-sys/src/boot/pc/ether8169.c - 664 sys sys 1121391787 18687
+sys/src/boot/pc/ether8169.c - 664 sys sys 1144961385 18634
 sys/src/boot/pc/ether82557.c - 664 sys sys 1140802406 19090
-sys/src/boot/pc/ether83815.c - 664 sys sys 1141485864 22026
+sys/src/boot/pc/ether83815.c - 664 sys sys 1144961190 21993
 sys/src/boot/pc/ether8390.c - 664 sys sys 1112382847 16209
 sys/src/boot/pc/ether8390.h - 664 sys sys 1015007951 1392
 sys/src/boot/pc/etherec2t.c - 664 sys sys 1015007951 3598
-sys/src/boot/pc/etherelnk3.c - 664 sys sys 1034454878 44068
+sys/src/boot/pc/etherelnk3.c - 664 sys sys 1144961190 44662
 sys/src/boot/pc/etherelnk3x.c - 664 sys sys 1015007951 24989
 sys/src/boot/pc/etherif.h - 664 sys sys 1107882190 1255
 sys/src/boot/pc/etherigbe.c - 664 sys sys 1140710606 40769
 sys/src/boot/pc/ethermii.c - 664 sys sys 1103641771 4413
 sys/src/boot/pc/ethermii.h - 664 sys sys 1071175087 3259
-sys/src/boot/pc/etherrhine.c - 664 sys sys 1071175087 12403
-sys/src/boot/pc/fns.h - 664 sys sys 1130887225 4273
+sys/src/boot/pc/etherrhine.c - 664 sys sys 1144961190 12383
+sys/src/boot/pc/fns.h - 664 sys sys 1144961190 4457
 sys/src/boot/pc/fs.c - 664 sys sys 1094674483 1509
 sys/src/boot/pc/fs.h - 664 sys sys 1094674488 653
 sys/src/boot/pc/ilock.c - 664 sys sys 1015007952 303
 sys/src/boot/pc/inflate.c - 664 sys sys 1021579984 2802
-sys/src/boot/pc/io.h - 664 sys sys 1015007952 5420
+sys/src/boot/pc/io.h - 664 sys sys 1144961190 6821
 sys/src/boot/pc/ip.h - 664 sys sys 1094674489 2461
 sys/src/boot/pc/kbd.c - 664 sys sys 1015007952 10188
 sys/src/boot/pc/kfs.h - 664 sys sys 1032215924 861
@@ -9053,7 +9054,7 @@ sys/src/boot/pc/load.c - 664 sys sys 1135487939 8923
 sys/src/boot/pc/mbr.s - 664 sys sys 1015007953 6234
 sys/src/boot/pc/mem.h - 664 sys sys 1130887225 3371
 sys/src/boot/pc/memory.c - 664 sys sys 1019533021 10272
-sys/src/boot/pc/mkfile - 664 sys sys 1103641863 3105
+sys/src/boot/pc/mkfile - 664 sys sys 1144961190 3112
 sys/src/boot/pc/noether.c - 664 sys sys 1094674488 358
 sys/src/boot/pc/part.c - 664 sys sys 1114697151 7153
 sys/src/boot/pc/pbs.s - 664 sys sys 1143465387 8291
@@ -9066,12 +9067,12 @@ sys/src/boot/pc/pci.c - 664 sys sys 1121366869 17898
 sys/src/boot/pc/print.c - 664 sys sys 1094674483 219
 sys/src/boot/pc/queue.c - 664 sys sys 1015007954 566
 sys/src/boot/pc/sd.h - 664 sys sys 1094674489 2271
-sys/src/boot/pc/sd53c8xx.c - 664 sys sys 1077033951 52135
+sys/src/boot/pc/sd53c8xx.c - 664 sys sys 1144961191 52127
 sys/src/boot/pc/sd53c8xx.i - 664 sys sys 1015007955 27245
-sys/src/boot/pc/sdata.c - 664 sys sys 1126906010 38224
-sys/src/boot/pc/sdmylex.c - 664 sys sys 1015007955 28743
-sys/src/boot/pc/sdscsi.c - 664 sys sys 1077033682 7022
-sys/src/boot/pc/trap.c - 664 sys sys 1130887225 7501
+sys/src/boot/pc/sdata.c - 664 sys sys 1144961191 38221
+sys/src/boot/pc/sdmylex.c - 664 sys sys 1144961191 28693
+sys/src/boot/pc/sdscsi.c - 664 sys sys 1144961224 7006
+sys/src/boot/pc/trap.c - 664 sys sys 1144961191 7499
 sys/src/boot/pc/ureg.h - 664 sys sys 1015007955 550
 sys/src/boot/pc/x16.h - 664 sys sys 1015007955 5265
 sys/src/cmd - 20000000775 sys sys 1018897673 0
@@ -12387,6 +12388,7 @@ sys/src/cmd/ip/snoopy/arp.c - 664 sys sys 1128179536 1914
 sys/src/cmd/ip/snoopy/bootp.c - 664 sys sys 1139667382 3442
 sys/src/cmd/ip/snoopy/dat.h - 664 sys sys 1128179536 1915
 sys/src/cmd/ip/snoopy/dhcp.c - 664 sys sys 1138463389 8958
+sys/src/cmd/ip/snoopy/dns.c - 664 sys sys 1144956777 14815
 sys/src/cmd/ip/snoopy/dump.c - 664 sys sys 1138463389 1078
 sys/src/cmd/ip/snoopy/eap.c - 664 sys sys 1128179537 3996
 sys/src/cmd/ip/snoopy/eap_identity.c - 664 sys sys 1128179537 50
@@ -12402,7 +12404,7 @@ sys/src/cmd/ip/snoopy/il.c - 664 sys sys 1139667365 2260
 sys/src/cmd/ip/snoopy/ip.c - 664 sys sys 1128179538 4300
 sys/src/cmd/ip/snoopy/ip6.c - 664 sys sys 1128179538 5371
 sys/src/cmd/ip/snoopy/main.c - 664 sys sys 1138463390 15607
-sys/src/cmd/ip/snoopy/mkfile - 664 sys sys 1139667360 885
+sys/src/cmd/ip/snoopy/mkfile - 664 sys sys 1144955678 889
 sys/src/cmd/ip/snoopy/ninep.c - 664 sys sys 1138463390 555
 sys/src/cmd/ip/snoopy/ospf.c - 664 sys sys 1138463391 7369
 sys/src/cmd/ip/snoopy/ppp.c - 664 sys sys 1128179539 10544
@@ -12417,9 +12419,9 @@ sys/src/cmd/ip/snoopy/rarp.c - 664 sys sys 1015090062 50
 sys/src/cmd/ip/snoopy/rc4keydesc.c - 664 sys sys 1128179539 56
 sys/src/cmd/ip/snoopy/rtcp.c - 664 sys sys 1138463392 1818
 sys/src/cmd/ip/snoopy/rtp.c - 664 sys sys 1138463392 1021
-sys/src/cmd/ip/snoopy/tcp.c - 664 sys sys 1139667382 3602
+sys/src/cmd/ip/snoopy/tcp.c - 664 sys sys 1144956781 3618
 sys/src/cmd/ip/snoopy/ttls.c - 664 sys sys 1128179540 1451
-sys/src/cmd/ip/snoopy/udp.c - 664 sys sys 1128179540 1999
+sys/src/cmd/ip/snoopy/udp.c - 664 sys sys 1144955685 2015
 sys/src/cmd/ip/telnet.c - 664 sys sys 1143759344 8614
 sys/src/cmd/ip/telnet.h - 664 sys sys 1015090250 5902
 sys/src/cmd/ip/telnetd.c - 664 sys sys 1135487948 11772
@@ -12633,17 +12635,17 @@ sys/src/cmd/ndb/cs.c - 664 sys sys 1134305453 33083
 sys/src/cmd/ndb/csgetval.c - 664 sys sys 957402051 1051
 sys/src/cmd/ndb/csquery.c - 664 sys sys 1014926159 1062
 sys/src/cmd/ndb/dblookup.c - 664 sys sys 1143759343 18249
-sys/src/cmd/ndb/dn.c - 664 sys sys 1127392642 27986
+sys/src/cmd/ndb/dn.c - 664 sys sys 1144952605 28763
 sys/src/cmd/ndb/dnarea.c - 664 sys sys 1121977162 2128
-sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1055701929 3062
-sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1143289655 15331
-sys/src/cmd/ndb/dns.c - 664 sys sys 1143759353 15287
-sys/src/cmd/ndb/dns.h - 664 sys sys 1143759354 10167
-sys/src/cmd/ndb/dnsdebug.c - 664 sys sys 1079747685 8488
+sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1144952605 3066
+sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1144952604 15346
+sys/src/cmd/ndb/dns.c - 664 sys sys 1144952604 15308
+sys/src/cmd/ndb/dns.h - 664 sys sys 1144969092 10171
+sys/src/cmd/ndb/dnsdebug.c - 664 sys sys 1144952604 8492
 sys/src/cmd/ndb/dnserver.c - 664 sys sys 1143759353 3982
 sys/src/cmd/ndb/dnsquery.c - 664 sys sys 1120564714 2198
-sys/src/cmd/ndb/dnstcp.c - 664 sys sys 1063861697 7085
-sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1055701924 5277
+sys/src/cmd/ndb/dnstcp.c - 664 sys sys 1144952604 7349
+sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1144969092 5337
 sys/src/cmd/ndb/ipquery.c - 664 sys sys 1124711426 773
 sys/src/cmd/ndb/mkdb.c - 664 sys sys 957402054 2886
 sys/src/cmd/ndb/mkfile - 664 sys sys 1055701930 1877
@@ -14058,7 +14060,7 @@ sys/src/cmd/usb/audio/usbaudio.h - 664 sys sys 1140695062 1889
 sys/src/cmd/usb/audio/usbaudioctl.c - 664 sys sys 1140695062 18245
 sys/src/cmd/usb/audio/usbaudioctl.h - 664 sys sys 1140695062 618
 sys/src/cmd/usb/lib - 20000000775 sys sys 1018369393 0
-sys/src/cmd/usb/lib/device.c - 664 sys sys 1137688747 3032
+sys/src/cmd/usb/lib/device.c - 664 sys sys 1144905083 3073
 sys/src/cmd/usb/lib/dump.c - 664 sys sys 1135896862 12915
 sys/src/cmd/usb/lib/fmt.c - 664 sys sys 1091204978 291
 sys/src/cmd/usb/lib/mkfile - 664 sys sys 1091204979 204
@@ -15625,3 +15627,5 @@ 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/9loaddebug - 775 sys sys 1144985392 312489
+386/9loadlitedebug - 775 sys sys 1144985393 200137

+ 34 - 32
dist/replica/plan9.db

@@ -1,8 +1,8 @@
 386 - 20000000775 sys sys 1010957353 0
 386/9load - 775 sys sys 1131317303 216948
-386/9loaddebug - 775 sys sys 1143931720 312489
+386/9loaddebug - 775 sys sys 1144985392 312489
 386/9loadlite - 775 sys sys 1131317306 135668
-386/9loadlitedebug - 775 sys sys 1143931720 200137
+386/9loadlitedebug - 775 sys sys 1144985393 200137
 386/9pc - 775 sys sys 1143137104 1913157
 386/9pc.gz - 664 sys sys 1141258202 668936
 386/9pccpu - 775 sys sys 1141258205 1583315
@@ -7954,7 +7954,7 @@ sys/src/9/pc/devusb.c - 664 sys sys 1105193103 18364
 sys/src/9/pc/devvga.c - 664 sys sys 1131290315 9332
 sys/src/9/pc/dma.c - 664 sys sys 1142966373 5332
 sys/src/9/pc/ether2000.c - 664 sys sys 1089299187 4819
-sys/src/9/pc/ether2114x.c - 664 sys sys 1081706476 41545
+sys/src/9/pc/ether2114x.c - 664 sys sys 1144963814 41694
 sys/src/9/pc/ether589.c - 664 sys sys 1015014516 4644
 sys/src/9/pc/ether79c970.c - 664 sys sys 1131290338 13953
 sys/src/9/pc/ether8003.c - 664 sys sys 1015014516 6665
@@ -9003,14 +9003,15 @@ sys/src/boot/pc/boot.c - 664 sys sys 1130887226 8421
 sys/src/boot/pc/bootld.c - 664 sys sys 1015007948 1801
 sys/src/boot/pc/bootp.c - 664 sys sys 1114464742 12374
 sys/src/boot/pc/cga.c - 664 sys sys 1015007948 1362
+sys/src/boot/pc/cis.c - 664 sys sys 1144961189 9232
 sys/src/boot/pc/clock.c - 664 sys sys 1103641772 6425
 sys/src/boot/pc/conf.c - 664 sys sys 1094674484 10217
 sys/src/boot/pc/console.c - 664 sys sys 1094674483 3388
-sys/src/boot/pc/dat.h - 664 sys sys 1109364490 3565
+sys/src/boot/pc/dat.h - 664 sys sys 1144961189 3597
 sys/src/boot/pc/devfloppy.c - 664 sys sys 1032215913 15505
 sys/src/boot/pc/devfloppy.h - 664 sys sys 1032409559 4081
-sys/src/boot/pc/devi82365.c - 664 sys sys 1019533020 23202
-sys/src/boot/pc/devpccard.c - 664 sys sys 1140711214 41433
+sys/src/boot/pc/devi82365.c - 664 sys sys 1144961189 15051
+sys/src/boot/pc/devpccard.c - 664 sys sys 1144961189 33938
 sys/src/boot/pc/devsd.c - 664 sys sys 1077033681 11262
 sys/src/boot/pc/dma.c - 664 sys sys 1015007949 4972
 sys/src/boot/pc/dosboot.c - 664 sys sys 1097716791 11240
@@ -9019,30 +9020,30 @@ sys/src/boot/pc/eoffs - 664 sys sys 1015007950 0
 sys/src/boot/pc/error.h - 664 sys sys 1015007950 3081
 sys/src/boot/pc/ether.c - 664 sys sys 1112382847 5090
 sys/src/boot/pc/ether2000.c - 664 sys sys 1015007950 2609
-sys/src/boot/pc/ether2114x.c - 664 sys sys 1066618033 37048
-sys/src/boot/pc/ether589.c - 664 sys sys 1107921511 4620
+sys/src/boot/pc/ether2114x.c - 664 sys sys 1144977462 38028
+sys/src/boot/pc/ether589.c - 664 sys sys 1144961189 4624
 sys/src/boot/pc/ether79c970.c - 664 sys sys 1015007950 11717
 sys/src/boot/pc/ether8003.c - 664 sys sys 1015007950 6446
 sys/src/boot/pc/ether8139.c - 664 sys sys 1121393459 14823
-sys/src/boot/pc/ether8169.c - 664 sys sys 1121391787 18687
+sys/src/boot/pc/ether8169.c - 664 sys sys 1144961385 18634
 sys/src/boot/pc/ether82557.c - 664 sys sys 1140802406 19090
-sys/src/boot/pc/ether83815.c - 664 sys sys 1141485864 22026
+sys/src/boot/pc/ether83815.c - 664 sys sys 1144961190 21993
 sys/src/boot/pc/ether8390.c - 664 sys sys 1112382847 16209
 sys/src/boot/pc/ether8390.h - 664 sys sys 1015007951 1392
 sys/src/boot/pc/etherec2t.c - 664 sys sys 1015007951 3598
-sys/src/boot/pc/etherelnk3.c - 664 sys sys 1034454878 44068
+sys/src/boot/pc/etherelnk3.c - 664 sys sys 1144961190 44662
 sys/src/boot/pc/etherelnk3x.c - 664 sys sys 1015007951 24989
 sys/src/boot/pc/etherif.h - 664 sys sys 1107882190 1255
 sys/src/boot/pc/etherigbe.c - 664 sys sys 1140710606 40769
 sys/src/boot/pc/ethermii.c - 664 sys sys 1103641771 4413
 sys/src/boot/pc/ethermii.h - 664 sys sys 1071175087 3259
-sys/src/boot/pc/etherrhine.c - 664 sys sys 1071175087 12403
-sys/src/boot/pc/fns.h - 664 sys sys 1130887225 4273
+sys/src/boot/pc/etherrhine.c - 664 sys sys 1144961190 12383
+sys/src/boot/pc/fns.h - 664 sys sys 1144961190 4457
 sys/src/boot/pc/fs.c - 664 sys sys 1094674483 1509
 sys/src/boot/pc/fs.h - 664 sys sys 1094674488 653
 sys/src/boot/pc/ilock.c - 664 sys sys 1015007952 303
 sys/src/boot/pc/inflate.c - 664 sys sys 1021579984 2802
-sys/src/boot/pc/io.h - 664 sys sys 1015007952 5420
+sys/src/boot/pc/io.h - 664 sys sys 1144961190 6821
 sys/src/boot/pc/ip.h - 664 sys sys 1094674489 2461
 sys/src/boot/pc/kbd.c - 664 sys sys 1015007952 10188
 sys/src/boot/pc/kfs.h - 664 sys sys 1032215924 861
@@ -9053,7 +9054,7 @@ sys/src/boot/pc/load.c - 664 sys sys 1135487939 8923
 sys/src/boot/pc/mbr.s - 664 sys sys 1015007953 6234
 sys/src/boot/pc/mem.h - 664 sys sys 1130887225 3371
 sys/src/boot/pc/memory.c - 664 sys sys 1019533021 10272
-sys/src/boot/pc/mkfile - 664 sys sys 1103641863 3105
+sys/src/boot/pc/mkfile - 664 sys sys 1144961190 3112
 sys/src/boot/pc/noether.c - 664 sys sys 1094674488 358
 sys/src/boot/pc/part.c - 664 sys sys 1114697151 7153
 sys/src/boot/pc/pbs.s - 664 sys sys 1143465387 8291
@@ -9066,12 +9067,12 @@ sys/src/boot/pc/pci.c - 664 sys sys 1121366869 17898
 sys/src/boot/pc/print.c - 664 sys sys 1094674483 219
 sys/src/boot/pc/queue.c - 664 sys sys 1015007954 566
 sys/src/boot/pc/sd.h - 664 sys sys 1094674489 2271
-sys/src/boot/pc/sd53c8xx.c - 664 sys sys 1077033951 52135
+sys/src/boot/pc/sd53c8xx.c - 664 sys sys 1144961191 52127
 sys/src/boot/pc/sd53c8xx.i - 664 sys sys 1015007955 27245
-sys/src/boot/pc/sdata.c - 664 sys sys 1126906010 38224
-sys/src/boot/pc/sdmylex.c - 664 sys sys 1015007955 28743
-sys/src/boot/pc/sdscsi.c - 664 sys sys 1077033682 7022
-sys/src/boot/pc/trap.c - 664 sys sys 1130887225 7501
+sys/src/boot/pc/sdata.c - 664 sys sys 1144961191 38221
+sys/src/boot/pc/sdmylex.c - 664 sys sys 1144961191 28693
+sys/src/boot/pc/sdscsi.c - 664 sys sys 1144961224 7006
+sys/src/boot/pc/trap.c - 664 sys sys 1144961191 7499
 sys/src/boot/pc/ureg.h - 664 sys sys 1015007955 550
 sys/src/boot/pc/x16.h - 664 sys sys 1015007955 5265
 sys/src/cmd - 20000000775 sys sys 1018897673 0
@@ -12387,6 +12388,7 @@ sys/src/cmd/ip/snoopy/arp.c - 664 sys sys 1128179536 1914
 sys/src/cmd/ip/snoopy/bootp.c - 664 sys sys 1139667382 3442
 sys/src/cmd/ip/snoopy/dat.h - 664 sys sys 1128179536 1915
 sys/src/cmd/ip/snoopy/dhcp.c - 664 sys sys 1138463389 8958
+sys/src/cmd/ip/snoopy/dns.c - 664 sys sys 1144956777 14815
 sys/src/cmd/ip/snoopy/dump.c - 664 sys sys 1138463389 1078
 sys/src/cmd/ip/snoopy/eap.c - 664 sys sys 1128179537 3996
 sys/src/cmd/ip/snoopy/eap_identity.c - 664 sys sys 1128179537 50
@@ -12402,7 +12404,7 @@ sys/src/cmd/ip/snoopy/il.c - 664 sys sys 1139667365 2260
 sys/src/cmd/ip/snoopy/ip.c - 664 sys sys 1128179538 4300
 sys/src/cmd/ip/snoopy/ip6.c - 664 sys sys 1128179538 5371
 sys/src/cmd/ip/snoopy/main.c - 664 sys sys 1138463390 15607
-sys/src/cmd/ip/snoopy/mkfile - 664 sys sys 1139667360 885
+sys/src/cmd/ip/snoopy/mkfile - 664 sys sys 1144955678 889
 sys/src/cmd/ip/snoopy/ninep.c - 664 sys sys 1138463390 555
 sys/src/cmd/ip/snoopy/ospf.c - 664 sys sys 1138463391 7369
 sys/src/cmd/ip/snoopy/ppp.c - 664 sys sys 1128179539 10544
@@ -12417,9 +12419,9 @@ sys/src/cmd/ip/snoopy/rarp.c - 664 sys sys 1015090062 50
 sys/src/cmd/ip/snoopy/rc4keydesc.c - 664 sys sys 1128179539 56
 sys/src/cmd/ip/snoopy/rtcp.c - 664 sys sys 1138463392 1818
 sys/src/cmd/ip/snoopy/rtp.c - 664 sys sys 1138463392 1021
-sys/src/cmd/ip/snoopy/tcp.c - 664 sys sys 1139667382 3602
+sys/src/cmd/ip/snoopy/tcp.c - 664 sys sys 1144956781 3618
 sys/src/cmd/ip/snoopy/ttls.c - 664 sys sys 1128179540 1451
-sys/src/cmd/ip/snoopy/udp.c - 664 sys sys 1128179540 1999
+sys/src/cmd/ip/snoopy/udp.c - 664 sys sys 1144955685 2015
 sys/src/cmd/ip/telnet.c - 664 sys sys 1143759344 8614
 sys/src/cmd/ip/telnet.h - 664 sys sys 1015090250 5902
 sys/src/cmd/ip/telnetd.c - 664 sys sys 1135487948 11772
@@ -12633,17 +12635,17 @@ sys/src/cmd/ndb/cs.c - 664 sys sys 1134305453 33083
 sys/src/cmd/ndb/csgetval.c - 664 sys sys 957402051 1051
 sys/src/cmd/ndb/csquery.c - 664 sys sys 1014926159 1062
 sys/src/cmd/ndb/dblookup.c - 664 sys sys 1143759343 18249
-sys/src/cmd/ndb/dn.c - 664 sys sys 1127392642 27986
+sys/src/cmd/ndb/dn.c - 664 sys sys 1144952605 28763
 sys/src/cmd/ndb/dnarea.c - 664 sys sys 1121977162 2128
-sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1055701929 3062
-sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1143289655 15331
-sys/src/cmd/ndb/dns.c - 664 sys sys 1143759353 15287
-sys/src/cmd/ndb/dns.h - 664 sys sys 1143759354 10167
-sys/src/cmd/ndb/dnsdebug.c - 664 sys sys 1079747685 8488
+sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1144952605 3066
+sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1144952604 15346
+sys/src/cmd/ndb/dns.c - 664 sys sys 1144952604 15308
+sys/src/cmd/ndb/dns.h - 664 sys sys 1144969092 10171
+sys/src/cmd/ndb/dnsdebug.c - 664 sys sys 1144952604 8492
 sys/src/cmd/ndb/dnserver.c - 664 sys sys 1143759353 3982
 sys/src/cmd/ndb/dnsquery.c - 664 sys sys 1120564714 2198
-sys/src/cmd/ndb/dnstcp.c - 664 sys sys 1063861697 7085
-sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1055701924 5277
+sys/src/cmd/ndb/dnstcp.c - 664 sys sys 1144952604 7349
+sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1144969092 5337
 sys/src/cmd/ndb/ipquery.c - 664 sys sys 1124711426 773
 sys/src/cmd/ndb/mkdb.c - 664 sys sys 957402054 2886
 sys/src/cmd/ndb/mkfile - 664 sys sys 1055701930 1877
@@ -14058,7 +14060,7 @@ sys/src/cmd/usb/audio/usbaudio.h - 664 sys sys 1140695062 1889
 sys/src/cmd/usb/audio/usbaudioctl.c - 664 sys sys 1140695062 18245
 sys/src/cmd/usb/audio/usbaudioctl.h - 664 sys sys 1140695062 618
 sys/src/cmd/usb/lib - 20000000775 sys sys 1018369393 0
-sys/src/cmd/usb/lib/device.c - 664 sys sys 1137688747 3032
+sys/src/cmd/usb/lib/device.c - 664 sys sys 1144905083 3073
 sys/src/cmd/usb/lib/dump.c - 664 sys sys 1135896862 12915
 sys/src/cmd/usb/lib/fmt.c - 664 sys sys 1091204978 291
 sys/src/cmd/usb/lib/mkfile - 664 sys sys 1091204979 204

+ 36 - 0
dist/replica/plan9.log

@@ -29451,3 +29451,39 @@
 1144697425 2 c 386/bin/cpp - 775 sys sys 1144696731 150554
 1144697425 3 c 386/bin/ps - 775 sys sys 1144696731 68907
 1144697425 4 c 386/bin/srv - 775 sys sys 1144696731 82908
+1144906298 0 c sys/src/cmd/usb/lib/device.c - 664 sys sys 1144905083 3073
+1144953111 0 c sys/src/cmd/ndb/dn.c - 664 sys sys 1144952605 28763
+1144953111 1 c sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1144952605 3066
+1144953111 2 c sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1144952604 15346
+1144953111 3 c sys/src/cmd/ndb/dns.c - 664 sys sys 1144952604 15308
+1144953111 4 c sys/src/cmd/ndb/dnsdebug.c - 664 sys sys 1144952604 8492
+1144953111 5 c sys/src/cmd/ndb/dnstcp.c - 664 sys sys 1144952604 7349
+1144953111 6 c sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1144952605 5283
+1144956714 0 a sys/src/cmd/ip/snoopy/dns.c - 664 sys sys 1144955676 14030
+1144956714 1 c sys/src/cmd/ip/snoopy/mkfile - 664 sys sys 1144955678 889
+1144956714 2 c sys/src/cmd/ip/snoopy/udp.c - 664 sys sys 1144955685 2015
+1144958515 0 c sys/src/cmd/ip/snoopy/dns.c - 664 sys sys 1144956777 14815
+1144958515 1 c sys/src/cmd/ip/snoopy/tcp.c - 664 sys sys 1144956781 3618
+1144962115 0 a sys/src/boot/pc/cis.c - 664 sys sys 1144961189 9232
+1144962115 1 c sys/src/boot/pc/dat.h - 664 sys sys 1144961189 3597
+1144962115 2 c sys/src/boot/pc/devi82365.c - 664 sys sys 1144961189 15051
+1144962115 3 c sys/src/boot/pc/devpccard.c - 664 sys sys 1144961189 33938
+1144962115 4 c sys/src/boot/pc/ether589.c - 664 sys sys 1144961189 4624
+1144962115 5 c sys/src/boot/pc/ether8169.c - 664 sys sys 1144961385 18634
+1144962115 6 c sys/src/boot/pc/ether83815.c - 664 sys sys 1144961190 21993
+1144962115 7 c sys/src/boot/pc/etherelnk3.c - 664 sys sys 1144961190 44662
+1144962115 8 c sys/src/boot/pc/etherrhine.c - 664 sys sys 1144961190 12383
+1144962115 9 c sys/src/boot/pc/fns.h - 664 sys sys 1144961190 4457
+1144962115 10 c sys/src/boot/pc/io.h - 664 sys sys 1144961190 6821
+1144962115 11 c sys/src/boot/pc/mkfile - 664 sys sys 1144961190 3112
+1144962115 12 c sys/src/boot/pc/sd53c8xx.c - 664 sys sys 1144961191 52127
+1144962115 13 c sys/src/boot/pc/sdata.c - 664 sys sys 1144961191 38221
+1144962115 14 c sys/src/boot/pc/sdmylex.c - 664 sys sys 1144961191 28693
+1144962115 15 c sys/src/boot/pc/sdscsi.c - 664 sys sys 1144961224 7006
+1144962115 16 c sys/src/boot/pc/trap.c - 664 sys sys 1144961191 7499
+1144963916 0 c sys/src/9/pc/ether2114x.c - 664 sys sys 1144963814 41694
+1144969317 0 c sys/src/cmd/ndb/dns.h - 664 sys sys 1144969092 10171
+1144969317 1 c sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1144969092 5337
+1144978320 0 c sys/src/boot/pc/ether2114x.c - 664 sys sys 1144977462 38028
+1144985523 0 c 386/9loaddebug - 775 sys sys 1144985392 312489
+1144985523 1 c 386/9loadlitedebug - 775 sys sys 1144985393 200137

+ 6 - 3
sys/src/9/pc/ether2114x.c

@@ -190,6 +190,7 @@ enum {					/* Variants */
 	Pnic		= (0x0002<<16)|0x11AD,
 	Pnic2		= (0xC115<<16)|0x11AD,
 	CentaurP	= (0x0985<<16)|0x1317,
+	CentaurPcb	= (0x1985<<16)|0x1317,
 };
 
 typedef struct Ctlr Ctlr;
@@ -1515,7 +1516,7 @@ srom(Ctlr* ctlr)
 			ctlr->srom[20+i+1] = ctlr->srom[i];
 		}
 	}
-	if(ctlr->id == CentaurP){
+	if(ctlr->id == CentaurP || ctlr->id == CentaurPcb){
 		memmove(&ctlr->srom[20], leafpnic, sizeof(leafpnic));
 		for(i = 0; i < Eaddrlen; i += 2){
 			ctlr->srom[20+i] = ctlr->srom[8+i];
@@ -1603,7 +1604,7 @@ srom(Ctlr* ctlr)
 	if(phy){
 		x = 0;
 		for(k = 0; k < nelem(ctlr->phy); k++){
-			if(ctlr->id == CentaurP && k != 1)
+			if((ctlr->id == CentaurP || ctlr->id == CentaurPcb) && k != 1)
 				continue;
 			if((oui = miir(ctlr, k, 2)) == -1 || oui == 0)
 				continue;
@@ -1655,6 +1656,7 @@ dec2114xpci(void)
 		case Pnic:			/* PNIC */
 		case Pnic2:			/* PNIC-II */
 		case CentaurP:			/* ADMtek */
+		case CentaurPcb:		/* ADMtek CardBus */
 			break;
 		}
 
@@ -1698,6 +1700,7 @@ dec2114xpci(void)
 			csr32w(ctlr, 15, 0x00000001);
 			break;
 		case CentaurP:
+		case CentaurPcb:
 			/*
 			 * Nice - the register offsets change from *8 to *4
 			 * for CSR16 and up...
@@ -1823,6 +1826,6 @@ reset(Ether* ether)
 void
 ether2114xlink(void)
 {
-	addethercard("21140",  reset);
 	addethercard("2114x",  reset);
+	addethercard("21140",  reset);
 }

+ 539 - 0
sys/src/boot/pc/cis.c

@@ -0,0 +1,539 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "error.h"
+#include "io.h"
+
+enum{
+	Linktarget = 0x13,
+};
+	
+/*
+ *  read and crack the card information structure enough to set
+ *  important parameters like power
+ */
+/* cis memory walking */
+typedef struct Cisdat {
+	uchar	*cisbase;
+	int	cispos;
+	int	cisskip;
+	int	cislen;
+} Cisdat;
+
+static void	tcfig(PCMslot*, Cisdat*, int);
+static void	tentry(PCMslot*, Cisdat*, int);
+static void	tvers1(PCMslot*, Cisdat*, int);
+static void	tlonglnkmfc(PCMslot*, Cisdat*, int);
+
+static int
+readc(Cisdat *cis, uchar *x)
+{
+	if(cis->cispos >= cis->cislen)
+		return 0;
+	*x = cis->cisbase[cis->cisskip*cis->cispos];
+	cis->cispos++;
+	return 1;
+}
+
+static int
+xcistuple(int slotno, int tuple, int subtuple, void *v, int nv, int attr)
+{
+	PCMmap *m;
+	Cisdat cis;
+	int i, l;
+	uchar *p;
+	uchar type, link, n, c;
+	int this, subtype;
+
+	m = pcmmap(slotno, 0, 0, attr);
+	if(m == 0)
+		return -1;
+
+	cis.cisbase = KADDR(m->isa);
+	cis.cispos = 0;
+	cis.cisskip = attr ? 2 : 1;
+	cis.cislen = m->len;
+
+	/* loop through all the tuples */
+	for(i = 0; i < 1000; i++){
+		this = cis.cispos;
+		if(readc(&cis, &type) != 1)
+			break;
+		if(type == 0xFF)
+			break;
+		if(readc(&cis, &link) != 1)
+			break;
+		if(link == 0xFF)
+			break;
+
+		n = link;
+		if(link > 1 && subtuple != -1){
+			if(readc(&cis, &c) != 1)
+				break;
+			subtype = c;
+			n--;
+		}else
+			subtype = -1;
+
+		if(type == tuple && subtype == subtuple){
+			p = v;
+			for(l=0; l<nv && l<n; l++)
+				if(readc(&cis, p++) != 1)
+					break;
+			pcmunmap(slotno, m);
+			return nv;
+		}
+		cis.cispos = this + (2+link);
+	}
+	pcmunmap(slotno, m);
+	return -1;
+}
+
+int
+pcmcistuple(int slotno, int tuple, int subtuple, void *v, int nv)
+{
+	int n;
+
+	/* try attribute space, then memory */
+	if((n = xcistuple(slotno, tuple, subtuple, v, nv, 1)) >= 0)
+		return n;
+	return xcistuple(slotno, tuple, subtuple, v, nv, 0);
+}
+
+void
+pcmcisread(PCMslot *pp)
+{
+	int this;
+	Cisdat cis;
+	PCMmap *m;
+	uchar type, link;
+
+	memset(pp->ctab, 0, sizeof(pp->ctab));
+	pp->ncfg = 0;
+	memset(pp->cfg, 0, sizeof(pp->cfg));
+	pp->configed = 0;
+	pp->nctab = 0;
+	pp->verstr[0] = 0;
+
+	/*
+	 * Read all tuples in attribute space.
+	 */
+	m = pcmmap(pp->slotno, 0, 0, 1);
+	if(m == 0)
+		return;
+
+	cis.cisbase = KADDR(m->isa);
+	cis.cispos = 0;
+	cis.cisskip = 2;
+	cis.cislen = m->len;
+
+	/* loop through all the tuples */
+	for(;;){
+		this = cis.cispos;
+		if(readc(&cis, &type) != 1)
+			break;
+		if(type == 0xFF)
+			break;
+		if(readc(&cis, &link) != 1)
+			break;
+
+		switch(type){
+		default:
+			break;
+		case 6:
+			tlonglnkmfc(pp, &cis, type);
+			break;
+		case 0x15:
+			tvers1(pp, &cis, type);
+			break;
+		case 0x1A:
+			tcfig(pp, &cis, type);
+			break;
+		case 0x1B:
+			tentry(pp, &cis, type);
+			break;
+		}
+
+		if(link == 0xFF)
+			break;
+		cis.cispos = this + (2+link);
+	}
+	pcmunmap(pp->slotno, m);
+}
+
+static ulong
+getlong(Cisdat *cis, int size)
+{
+	uchar c;
+	int i;
+	ulong x;
+
+	x = 0;
+	for(i = 0; i < size; i++){
+		if(readc(cis, &c) != 1)
+			break;
+		x |= c<<(i*8);
+	}
+	return x;
+}
+
+static void
+tcfig(PCMslot *pp, Cisdat *cis, int )
+{
+	uchar size, rasize, rmsize;
+	uchar last;
+
+	if(readc(cis, &size) != 1)
+		return;
+	rasize = (size&0x3) + 1;
+	rmsize = ((size>>2)&0xf) + 1;
+	if(readc(cis, &last) != 1)
+		return;
+
+	if(pp->ncfg >= 8){
+		print("tcfig: too many configuration registers\n");
+		return;
+	}
+	
+	pp->cfg[pp->ncfg].caddr = getlong(cis, rasize);
+	pp->cfg[pp->ncfg].cpresent = getlong(cis, rmsize);
+	pp->ncfg++;
+}
+
+static ulong vexp[8] =
+{
+	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
+};
+static ulong vmant[16] =
+{
+	10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90,
+};
+
+static ulong
+microvolt(Cisdat *cis)
+{
+	uchar c;
+	ulong microvolts;
+	ulong exp;
+
+	if(readc(cis, &c) != 1)
+		return 0;
+	exp = vexp[c&0x7];
+	microvolts = vmant[(c>>3)&0xf]*exp;
+	while(c & 0x80){
+		if(readc(cis, &c) != 1)
+			return 0;
+		switch(c){
+		case 0x7d:
+			break;		/* high impedence when sleeping */
+		case 0x7e:
+		case 0x7f:
+			microvolts = 0;	/* no connection */
+			break;
+		default:
+			exp /= 10;
+			microvolts += exp*(c&0x7f);
+		}
+	}
+	return microvolts;
+}
+
+static ulong
+nanoamps(Cisdat *cis)
+{
+	uchar c;
+	ulong nanoamps;
+
+	if(readc(cis, &c) != 1)
+		return 0;
+	nanoamps = vexp[c&0x7]*vmant[(c>>3)&0xf];
+	while(c & 0x80){
+		if(readc(cis, &c) != 1)
+			return 0;
+		if(c == 0x7d || c == 0x7e || c == 0x7f)
+			nanoamps = 0;
+	}
+	return nanoamps;
+}
+
+/*
+ * only nominal voltage (feature 1) is important for config,
+ * other features must read card to stay in sync.
+ */
+static ulong
+power(Cisdat *cis)
+{
+	uchar feature;
+	ulong mv;
+
+	mv = 0;
+	if(readc(cis, &feature) != 1)
+		return 0;
+	if(feature & 1)
+		mv = microvolt(cis);
+	if(feature & 2)
+		microvolt(cis);
+	if(feature & 4)
+		microvolt(cis);
+	if(feature & 8)
+		nanoamps(cis);
+	if(feature & 0x10)
+		nanoamps(cis);
+	if(feature & 0x20)
+		nanoamps(cis);
+	if(feature & 0x40)
+		nanoamps(cis);
+	return mv/1000000;
+}
+
+static ulong mantissa[16] =
+{ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, };
+
+static ulong exponent[8] =
+{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, };
+
+static ulong
+ttiming(Cisdat *cis, int scale)
+{
+	uchar unscaled;
+	ulong nanosecs;
+
+	if(readc(cis, &unscaled) != 1)
+		return 0;
+	nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;
+	nanosecs = nanosecs * vexp[scale];
+	return nanosecs;
+}
+
+static void
+timing(Cisdat *cis, PCMconftab *ct)
+{
+	uchar c, i;
+
+	if(readc(cis, &c) != 1)
+		return;
+	i = c&0x3;
+	if(i != 3)
+		ct->maxwait = ttiming(cis, i);		/* max wait */
+	i = (c>>2)&0x7;
+	if(i != 7)
+		ct->readywait = ttiming(cis, i);		/* max ready/busy wait */
+	i = (c>>5)&0x7;
+	if(i != 7)
+		ct->otherwait = ttiming(cis, i);		/* reserved wait */
+}
+
+static void
+iospaces(Cisdat *cis, PCMconftab *ct)
+{
+	uchar c;
+	int i, nio;
+
+	ct->nio = 0;
+	if(readc(cis, &c) != 1)
+		return;
+
+	ct->bit16 = ((c>>5)&3) >= 2;
+	if(!(c & 0x80)){
+		ct->io[0].start = 0;
+		ct->io[0].len = 1<<(c&0x1f);
+		ct->nio = 1;
+		return;
+	}
+
+	if(readc(cis, &c) != 1)
+		return;
+
+	/*
+	 * For each of the range descriptions read the
+	 * start address and the length (value is length-1).
+	 */
+	nio = (c&0xf)+1;
+	for(i = 0; i < nio; i++){
+		ct->io[i].start = getlong(cis, (c>>4)&0x3);
+		ct->io[i].len = getlong(cis, (c>>6)&0x3)+1;
+	}
+	ct->nio = nio;
+}
+
+static void
+irq(Cisdat *cis, PCMconftab *ct)
+{
+	uchar c;
+
+	if(readc(cis, &c) != 1)
+		return;
+	ct->irqtype = c & 0xe0;
+	if(c & 0x10)
+		ct->irqs = getlong(cis, 2);
+	else
+		ct->irqs = 1<<(c&0xf);
+	ct->irqs &= 0xDEB8;		/* levels available to card */
+}
+
+static void
+memspace(Cisdat *cis, int asize, int lsize, int host)
+{
+	ulong haddress, address, len;
+
+	len = getlong(cis, lsize)*256;
+	address = getlong(cis, asize)*256;
+	USED(len, address);
+	if(host){
+		haddress = getlong(cis, asize)*256;
+		USED(haddress);
+	}
+}
+
+static void
+tentry(PCMslot *pp, Cisdat *cis, int )
+{
+	uchar c, i, feature;
+	PCMconftab *ct;
+
+	if(pp->nctab >= nelem(pp->ctab))
+		return;
+	if(readc(cis, &c) != 1)
+		return;
+	ct = &pp->ctab[pp->nctab++];
+
+	/* copy from last default config */
+	if(pp->def)
+		*ct = *pp->def;
+
+	ct->index = c & 0x3f;
+
+	/* is this the new default? */
+	if(c & 0x40)
+		pp->def = ct;
+
+	/* memory wait specified? */
+	if(c & 0x80){
+		if(readc(cis, &i) != 1)
+			return;
+		if(i&0x80)
+			ct->memwait = 1;
+	}
+
+	if(readc(cis, &feature) != 1)
+		return;
+	switch(feature&0x3){
+	case 1:
+		ct->vpp1 = ct->vpp2 = power(cis);
+		break;
+	case 2:
+		power(cis);
+		ct->vpp1 = ct->vpp2 = power(cis);
+		break;
+	case 3:
+		power(cis);
+		ct->vpp1 = power(cis);
+		ct->vpp2 = power(cis);
+		break;
+	default:
+		break;
+	}
+	if(feature&0x4)
+		timing(cis, ct);
+	if(feature&0x8)
+		iospaces(cis, ct);
+	if(feature&0x10)
+		irq(cis, ct);
+	switch((feature>>5)&0x3){
+	case 1:
+		memspace(cis, 0, 2, 0);
+		break;
+	case 2:
+		memspace(cis, 2, 2, 0);
+		break;
+	case 3:
+		if(readc(cis, &c) != 1)
+			return;
+		for(i = 0; i <= (c&0x7); i++)
+			memspace(cis, (c>>5)&0x3, (c>>3)&0x3, c&0x80);
+		break;
+	}
+	pp->configed++;
+}
+
+static void
+tvers1(PCMslot *pp, Cisdat *cis, int )
+{
+	uchar c, major, minor, last;
+	int  i;
+
+	if(readc(cis, &major) != 1)
+		return;
+	if(readc(cis, &minor) != 1)
+		return;
+	last = 0;
+	for(i = 0; i < sizeof(pp->verstr)-1; i++){
+		if(readc(cis, &c) != 1)
+			return;
+		if(c == 0)
+			c = ';';
+		if(c == '\n')
+			c = ';';
+		if(c == 0xff)
+			break;
+		if(c == ';' && last == ';')
+			continue;
+		pp->verstr[i] = c;
+		last = c;
+	}
+	pp->verstr[i] = 0;
+}
+
+static void
+tlonglnkmfc(PCMslot *pp, Cisdat *cis, int)
+{
+	int i, npos, opos;
+	uchar nfn, space, expect, type, this, link;
+
+	readc(cis, &nfn);
+	for(i = 0; i < nfn; i++){
+		readc(cis, &space);
+		npos        = getlong(cis, 4);
+		opos        = cis->cispos;
+		cis->cispos = npos;
+		expect      = Linktarget;
+
+		while(1){
+			this = cis->cispos;
+			if(readc(cis, &type) != 1)
+				break;
+			if(type == 0xFF)
+				break;
+			if(readc(cis, &link) != 1)
+				break;
+
+			if(expect && expect != type){
+				print("tlonglnkmfc: expected %X found %X\n",
+					expect, type);
+				break;
+			}
+			expect = 0;
+
+			switch(type){
+			default:
+				break;
+			case 0x15:
+				tvers1(pp, cis, type);
+				break;
+			case 0x1A:
+				tcfig(pp, cis, type);
+				break;
+			case 0x1B:
+				tentry(pp, cis, type);
+				break;
+			}
+
+			if(link == 0xFF)
+				break;
+			cis->cispos = this + (2+link);
+		}
+		cis->cispos = opos;
+	}
+}

+ 1 - 0
sys/src/boot/pc/dat.h

@@ -112,6 +112,7 @@ typedef struct  ISAConf {
 
 typedef struct Pcidev Pcidev;
 typedef struct PCMmap PCMmap;
+typedef struct PCMslot PCMslot;
 
 #define BOOTLINE	((char*)CONFADDR)
 

+ 83 - 546
sys/src/boot/pc/devi82365.c

@@ -7,15 +7,7 @@
 #include "io.h"
 
 /*
- *  Support for up to 4 Slot card slots.  Generalizing above that is hard
- *  since addressing is not obvious. - presotto
- *
- *  WARNING: This has never been tried with more than one card slot.
- */
-
-/*
- *  Intel 82365SL PCIC controller for the PCMCIA or
- *  Cirrus Logic PD6710/PD6720 which is mostly register compatible
+ *  Intel 82365SL PCIC controller and compatibles.
  */
 enum
 {
@@ -84,10 +76,6 @@ enum
 	Moffhi=		0x5,		/* Card memory offset address high byte */
 	 Fregactive=	 (1<<6),	/*  attribute memory */
 
-	Mbits=		13,		/* msb of Mchunk */
-	Mchunk=		1<<Mbits,	/* logical mapping granularity */
-	Nmap=		4,		/* max number of maps to use */
-
 	/*
 	 *  configuration registers - they start at an offset in attribute
 	 *  memory found in the CIS.
@@ -95,8 +83,12 @@ enum
 	Rconfig=	0,
 	 Creset=	 (1<<7),	/*  reset device */
 	 Clevel=	 (1<<6),	/*  level sensitive interrupt line */
-
-	Maxctab=	8,		/* maximum configuration table entries */
+	 Cirq=		 (1<<2),	/*  IRQ enable */
+	 Cdecode=	 (1<<1),	/*  address decode */
+	 Cfunc=		 (1<<0),	/*  function enable */
+	Riobase0=	5,
+	Riobase1=	6,
+	Riosize=	9,
 };
 
 static int pcmcia_pcmspecial(char *, ISAConf *);
@@ -105,9 +97,7 @@ static void pcmcia_pcmspecialclose(int);
 #define MAP(x,o)	(Rmap + (x)*0x8 + o)
 
 typedef struct I82365	I82365;
-typedef struct Slot	Slot;
-typedef struct Conftab	Conftab;
-typedef struct Cisdat	Cisdat;
+
 /* a controller */
 enum
 {
@@ -127,96 +117,29 @@ struct I82365
 };
 static I82365 *controller[4];
 static int ncontroller;
-
-/* configuration table entry */
-struct Conftab
-{
-	int	index;
-	ushort	irqs;		/* legal irqs */
-	uchar	irqtype;
-	uchar	bit16;		/* true for 16 bit access */
-	struct {
-		ulong	start;
-		ulong	len;
-	} io[16];
-	int	nio;
-	uchar	vpp1;
-	uchar	vpp2;
-	uchar	memwait;
-	ulong	maxwait;
-	ulong	readywait;
-	ulong	otherwait;
-};
-
-/* cis memory walking */
-struct Cisdat
-{
-	uchar	*cisbase;
-	int	cispos;
-	int	cisskip;
-	int	cislen;
-};
-
-/* a card slot */
-struct Slot
-{
-	Lock;
-	int	ref;
-
-	I82365	*cp;		/* controller for this slot */
-	long	memlen;		/* memory length */
-	uchar	base;		/* index register base */
-	uchar	slotno;		/* slot number */
-
-	/* status */
-	uchar	special;	/* in use for a special device */
-	uchar	already;	/* already inited */
-	uchar	occupied;
-	uchar	battery;
-	uchar	wrprot;
-	uchar	powered;
-	uchar	configed;
-	uchar	enabled;
-	uchar	busy;
-
-	/* cis info */
-	char	verstr[512];	/* version string */
-	uchar	cpresent;	/* config registers present */
-	ulong	caddr;		/* relative address of config registers */
-	int	nctab;		/* number of config table entries */
-	Conftab	ctab[Maxctab];
-	Conftab	*def;		/* default conftab */
-
-	/* for walking through cis */
-	Cisdat;
-
-	/* memory maps */
-	Lock	mlock;		/* lock down the maps */
-	int	time;
-	PCMmap	mmap[Nmap];	/* maps, last is always for the kernel */
-};
-static Slot	*slot;
-static Slot	*lastslot;
+static PCMslot	*slot;
+static PCMslot	*lastslot;
 static nslot;
 
-static void	cisread(Slot*);
 static void	i82365intr(Ureg*, void*);
 static void	i82365reset(void);
 static int	pcmio(int, ISAConf*);
-static long	pcmread(int, int, void*, long, vlong);
-static long	pcmwrite(int, int, void*, long, vlong);
 
-static void i82365dump(Slot*);
+static void i82365dump(PCMslot*);
 
 void
 devi82365link(void)
 {
 	static int already;
+	char *p;
 
 	if(already)
 		return;
 	already = 1;
 
+	if((p=getconf("pcmcia0")) && strncmp(p, "disabled", 8)==0)
+		return;
+
 	if (_pcmspecial)
 		return;
 	
@@ -228,23 +151,23 @@ devi82365link(void)
  *  reading and writing card registers
  */
 static uchar
-rdreg(Slot *pp, int index)
+rdreg(PCMslot *pp, int index)
 {
-	outb(pp->cp->xreg, pp->base + index);
-	return inb(pp->cp->dreg);
+	outb(((I82365*)pp->cp)->xreg, pp->base + index);
+	return inb(((I82365*)pp->cp)->dreg);
 }
 static void
-wrreg(Slot *pp, int index, uchar val)
+wrreg(PCMslot *pp, int index, uchar val)
 {
-	outb(pp->cp->xreg, pp->base + index);
-	outb(pp->cp->dreg, val);
+	outb(((I82365*)pp->cp)->xreg, pp->base + index);
+	outb(((I82365*)pp->cp)->dreg, val);
 }
 
 /*
  *  get info about card
  */
 static void
-slotinfo(Slot *pp)
+slotinfo(PCMslot *pp)
 {
 	uchar isr;
 
@@ -254,6 +177,7 @@ slotinfo(Slot *pp)
 	pp->battery = (isr & 3) == 3;
 	pp->wrprot = isr & (1<<4);
 	pp->busy = isr & (1<<5);
+	//pp->msec = TK2MS(MACHP(0)->ticks);
 }
 
 static int
@@ -273,7 +197,7 @@ vcode(int volt)
  *  enable the slot card
  */
 static void
-slotena(Slot *pp)
+slotena(PCMslot *pp)
 {
 	if(pp->enabled)
 		return;
@@ -289,7 +213,7 @@ slotena(Slot *pp)
 	/* get configuration */
 	slotinfo(pp);
 	if(pp->occupied){
-		cisread(pp);
+		pcmcisread(pp);
 		pp->enabled = 1;
 	} else
 		wrreg(pp, Rpc, Fautopower);
@@ -299,7 +223,7 @@ slotena(Slot *pp)
  *  disable the slot card
  */
 static void
-slotdis(Slot *pp)
+slotdis(PCMslot *pp)
 {
 	wrreg(pp, Rpc, 0);	/* turn off card power */
 	wrreg(pp, Rwe, 0);	/* no windows */
@@ -313,7 +237,7 @@ static void
 i82365intr(Ureg *, void *)
 {
 	uchar csc, was;
-	Slot *pp;
+	PCMslot *pp;
 
 	if(slot == 0)
 		return;
@@ -342,7 +266,7 @@ enum
 PCMmap*
 pcmmap(int slotno, ulong offset, int len, int attr)
 {
-	Slot *pp;
+	PCMslot *pp;
 	uchar we, bit;
 	PCMmap *m, *nm;
 	int i;
@@ -362,7 +286,7 @@ pcmmap(int slotno, ulong offset, int len, int attr)
 	we = rdreg(pp, Rwe);
 	bit = 1;
 	nm = 0;
-	for(m = pp->mmap; m < &pp->mmap[Nmap]; m++){
+	for(m = pp->mmap; m < &pp->mmap[nelem(pp->mmap)]; m++){
 		if((we & bit))
 		if(m->attr == attr)
 		if(offset >= m->ca && e <= m->cea){
@@ -422,7 +346,7 @@ pcmmap(int slotno, ulong offset, int len, int attr)
 void
 pcmunmap(int slotno, PCMmap* m)
 {
-	Slot *pp;
+	PCMslot *pp;
 
 	pp = slot + slotno;
 	lock(&pp->mlock);
@@ -431,7 +355,7 @@ pcmunmap(int slotno, PCMmap* m)
 }
 
 static void
-increfp(Slot *pp)
+increfp(PCMslot *pp)
 {
 	lock(pp);
 	if(pp->ref++ == 0)
@@ -440,7 +364,7 @@ increfp(Slot *pp)
 }
 
 static void
-decrefp(Slot *pp)
+decrefp(PCMslot *pp)
 {
 	lock(pp);
 	if(pp->ref-- == 1)
@@ -454,7 +378,7 @@ decrefp(Slot *pp)
 static int
 pcmcia_pcmspecial(char *idstr, ISAConf *isa)
 {
-	Slot *pp;
+	PCMslot *pp;
 	extern char *strstr(char*, char*);
 	int enabled;
 
@@ -472,9 +396,11 @@ pcmcia_pcmspecial(char *idstr, ISAConf *isa)
 		}
 
 		if(pp->occupied) {
-			if(strstr(pp->verstr, idstr)) {
-				if (!enabled)
+			if(strstr(pp->verstr, idstr)){
+				if (!enabled){
+					enabled = 1;
 					increfp(pp);
+				}
 				if(isa == 0 || pcmio(pp->slotno, isa) == 0){
 					pp->special = 1;
 					return pp->slotno;
@@ -491,7 +417,7 @@ pcmcia_pcmspecial(char *idstr, ISAConf *isa)
 static void
 pcmcia_pcmspecialclose(int slotno)
 {
-	Slot *pp;
+	PCMslot *pp;
 
 	print("pcmspecialclose called\n");
 	if(slotno >= nslot)
@@ -520,7 +446,9 @@ i82365probe(int x, int d, int dev)
 	outb(x, Rid + (dev<<7));
 	id = inb(d);
 	if((id & 0xf0) != 0x80)
-		return 0;		/* not this family */
+		return 0;		/* not a memory & I/O card */
+	if((id & 0x0f) == 0x00)
+		return 0;		/* no revision number, not possible */
 
 	cp = xalloc(sizeof(I82365));
 	cp->xreg = x;
@@ -556,18 +484,22 @@ i82365probe(int x, int d, int dev)
 		break;
 	}
 
+	/* if it's not a Cirrus, it could be a Vadem... */
 	if(cp->type == Ti82365){
+		/* unlock the Vadem extended regs */
 		outb(x, 0x0E + (dev<<7));
 		outb(x, 0x37 + (dev<<7));
+
+		/* make the id register show the Vadem id */
 		outb(x, 0x3A + (dev<<7));
 		c = inb(d);
 		outb(d, c|0xC0);
 		outb(x, Rid + (dev<<7));
 		c = inb(d);
-		if(c != id && !(c & 0x08))
-			print("#y%d: id %uX changed to %uX\n", ncontroller, id, c);
 		if(c & 0x08)
 			cp->type = Tvg46x;
+
+		/* go back to Intel compatible id */
 		outb(x, 0x3A + (dev<<7));
 		c = inb(d);
 		outb(d, c & ~0xC0);
@@ -592,7 +524,7 @@ i82365probe(int x, int d, int dev)
 }
 
 static void
-i82365dump(Slot *pp)
+i82365dump(PCMslot *pp)
 {
 	int i;
 
@@ -615,7 +547,7 @@ i82365reset(void)
 	static int already;
 	int i, j;
 	I82365 *cp;
-	Slot *pp;
+	PCMslot *pp;
 
 	if(already)
 		return;
@@ -630,9 +562,8 @@ i82365reset(void)
 
 	for(i = 0; i < ncontroller; i++)
 		nslot += controller[i]->nslot;
-	slot = xalloc(nslot * sizeof(Slot));
+	slot = xalloc(nslot * sizeof(PCMslot));
 
-	/* if the card is there turn on 5V power to keep its battery alive */
 	lastslot = slot;
 	for(i = 0; i < ncontroller; i++){
 		cp = controller[i];
@@ -644,6 +575,8 @@ i82365reset(void)
 			pp->memlen = 64*MB;
 			pp->base = (cp->dev<<7) | (j<<6);
 			pp->cp = cp;
+			pp->msec = ~0;
+			pp->verstr[0] = 0;
 			slotdis(pp);
 
 			/* interrupt on status change */
@@ -657,15 +590,15 @@ i82365reset(void)
 }
 
 /*
- *  configure the Slot for IO.  We assume very heavily that we can read
+ *  configure the PCMslot for IO.  We assume very heavily that we can read
  *  configuration info from the CIS.  If not, we won't set up correctly.
  */
 static int
 pcmio(int slotno, ISAConf *isa)
 {
 	uchar we, x, *p;
-	Slot *pp;
-	Conftab *ct, *et, *t;
+	PCMslot *pp;
+	PCMconftab *ct, *et, *t;
 	PCMmap *m;
 	int i, index, irq;
 	char *cp;
@@ -692,6 +625,7 @@ pcmio(int slotno, ISAConf *isa)
 			return -1;
 		ct = &pp->ctab[index];
 	}
+
 	if(ct == 0){
 	
 		/* assume default is right */
@@ -749,7 +683,10 @@ pcmio(int slotno, ISAConf *isa)
 		x |= x<<4;
 	wrreg(pp, Rio, x);
 
-	/* enable io port map 0 */
+	/*
+	 * enable io port map 0
+	 * the 'top' register value includes the last valid address
+	 */
 	if(isa->port == 0)
 		isa->port = ct->io[0].start;
 	we = rdreg(pp, Rwe);
@@ -759,7 +696,7 @@ pcmio(int slotno, ISAConf *isa)
 	wrreg(pp, Riotop0lo, i);
 	wrreg(pp, Riotop0hi, i>>8);
 	we |= 1<<6;
-	if(ct->nio == 2 && ct->io[1].start){
+	if(ct->nio >= 2 && ct->io[1].start){
 		wrreg(pp, Riobtm1lo, ct->io[1].start);
 		wrreg(pp, Riobtm1hi, ct->io[1].start>>8);
 		i = ct->io[1].start+ct->io[1].len-1;
@@ -770,436 +707,36 @@ pcmio(int slotno, ISAConf *isa)
 	wrreg(pp, Rwe, we);
 
 	/* only touch Rconfig if it is present */
-	if(pp->cpresent & (1<<Rconfig)){
+	m = pcmmap(slotno, pp->cfg[0].caddr + Rconfig, 0x20, 1);
+	p = KADDR(m->isa + pp->cfg[0].caddr - m->ca);
+	if(pp->cfg[0].cpresent & (1<<Rconfig)){
 		/*  Reset adapter */
-		m = pcmmap(slotno, pp->caddr + Rconfig, 1, 1);
-		p = KADDR(m->isa + pp->caddr + Rconfig - m->ca);
 
-		/* set configuration and interrupt type */
+		/*  set configuration and interrupt type.
+		 *  if level is possible on the card, use it.
+		 */
 		x = ct->index;
-		if((ct->irqtype & 0x20) && ((ct->irqtype & 0x40)==0 || isa->irq>7))
+		if(ct->irqtype & 0x20)
 			x |= Clevel;
-		*p = x;
-		delay(5);
-
-		pcmunmap(slotno, m);
-	}
-	return 0;
-}
-
-/*
- *  read and crack the card information structure enough to set
- *  important parameters like power
- */
-static void	tcfig(Slot*, Cisdat*, int);
-static void	tentry(Slot*, Cisdat*, int);
-static void	tvers1(Slot*, Cisdat*, int);
-
-struct {
-	int n;
-	void (*parse)(Slot*, Cisdat*, int);
-} cistab[] = {
-	0x15, tvers1,
-	0x1A, tcfig,
-	0x1B, tentry,
-};
-
-static int
-readc(Cisdat *pp, uchar *x)
-{
-	if(pp->cispos >= pp->cislen)
-		return 0;
-	*x = pp->cisbase[pp->cisskip*pp->cispos];
-	pp->cispos++;
-	return 1;
-}
-
-static int
-xcistuple(int slotno, int tuple, void *v, int nv, int attr)
-{
-	PCMmap *m;
-	Cisdat cis;
-	int i, l;
-	uchar *p;
-	uchar type, link;
-	int this;
-
-	m = pcmmap(slotno, 0, 0, attr);
-	if(m == 0) {
-if(debug) print("could not map\n");
-		return -1;
-	}
-
-	cis.cisbase = KADDR(m->isa);
-	cis.cispos = 0;
-	cis.cisskip = attr ? 2 : 1;
-	cis.cislen = Mchunk;
-
-if(debug) print("cis %d %d #%lux srch %x...", attr, cis.cisskip, cis.cisbase, tuple);
-	/* loop through all the tuples */
-	for(i = 0; i < 1000; i++){
-		this = cis.cispos;
-		if(readc(&cis, &type) != 1)
-			break;
-if(debug) print("%2ux...", type);
-		if(type == 0xFF)
-			break;
-		if(readc(&cis, &link) != 1)
-			break;
-		if(link == 0xFF)
-			break;
-		if(type == tuple) {
-			p = v;
-			for(l=0; l<nv && l<link; l++)
-				if(readc(&cis, p++) != 1)
-					break;
-			pcmunmap(slotno, m);
-if(debug) print("pcm find %2.2ux %d %d\n", type, link, l);
-			return l;
-		}
-		cis.cispos = this + (2+link);
-	}
-	pcmunmap(slotno, m);
-	return -1;
-}
-
-int
-pcmcistuple(int slotno, int tuple, void *v, int nv)
-{
-	int n;
-
-	/* try attribute space, then memory */
-	if((n = xcistuple(slotno, tuple, v, nv, 1)) >= 0)
-		return n;
-	return xcistuple(slotno, tuple, v, nv, 0);
-}
-
-static void
-cisread(Slot *pp)
-{
-	uchar v[256];
-	int i, nv;
-	Cisdat cis;
-
-	memset(pp->ctab, 0, sizeof(pp->ctab));
-	pp->caddr = 0;
-	pp->cpresent = 0;
-	pp->configed = 0;
-	pp->nctab = 0;
-
-	for(i = 0; i < nelem(cistab); i++) {
-		if((nv = pcmcistuple(pp->slotno, cistab[i].n, v, sizeof(v))) >= 0) {
-			cis.cisbase = v;
-			cis.cispos = 0;
-			cis.cisskip = 1;
-			cis.cislen = nv;
-			
-			(*cistab[i].parse)(pp, &cis, cistab[i].n);
-		}
-	}
-}
-
-static ulong
-getlong(Cisdat *cis, int size)
-{
-	uchar c;
-	int i;
-	ulong x;
-
-	x = 0;
-	for(i = 0; i < size; i++){
-		if(readc(cis, &c) != 1)
-			break;
-		x |= c<<(i*8);
-	}
-	return x;
-}
-
-static void
-tcfig(Slot *pp, Cisdat *cis, int )
-{
-	uchar size, rasize, rmsize;
-	uchar last;
-
-	if(readc(cis, &size) != 1)
-		return;
-	rasize = (size&0x3) + 1;
-	rmsize = ((size>>2)&0xf) + 1;
-	if(readc(cis, &last) != 1)
-		return;
-	pp->caddr = getlong(cis, rasize);
-	pp->cpresent = getlong(cis, rmsize);
-}
-
-static ulong vexp[8] =
-{
-	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
-};
-static ulong vmant[16] =
-{
-	10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90,
-};
-
-static ulong
-microvolt(Cisdat *cis)
-{
-	uchar c;
-	ulong microvolts;
-	ulong exp;
-
-	if(readc(cis, &c) != 1)
-		return 0;
-	exp = vexp[c&0x7];
-	microvolts = vmant[(c>>3)&0xf]*exp;
-	while(c & 0x80){
-		if(readc(cis, &c) != 1)
-			return 0;
-		switch(c){
-		case 0x7d:
-			break;		/* high impedence when sleeping */
-		case 0x7e:
-		case 0x7f:
-			microvolts = 0;	/* no connection */
-			break;
-		default:
-			exp /= 10;
-			microvolts += exp*(c&0x7f);
-		}
-	}
-	return microvolts;
-}
-
-static ulong
-nanoamps(Cisdat *cis)
-{
-	uchar c;
-	ulong nanoamps;
-
-	if(readc(cis, &c) != 1)
-		return 0;
-	nanoamps = vexp[c&0x7]*vmant[(c>>3)&0xf];
-	while(c & 0x80){
-		if(readc(cis, &c) != 1)
-			return 0;
-		if(c == 0x7d || c == 0x7e || c == 0x7f)
-			nanoamps = 0;
-	}
-	return nanoamps;
-}
-
-/*
- *  only nominal voltage is important for config
- */
-static ulong
-power(Cisdat *cis)
-{
-	uchar feature;
-	ulong mv;
-
-	mv = 0;
-	if(readc(cis, &feature) != 1)
-		return 0;
-	if(feature & 1)
-		mv = microvolt(cis);
-	if(feature & 2)
-		microvolt(cis);
-	if(feature & 4)
-		microvolt(cis);
-	if(feature & 8)
-		nanoamps(cis);
-	if(feature & 0x10)
-		nanoamps(cis);
-	if(feature & 0x20)
-		nanoamps(cis);
-	if(feature & 0x40)
-		nanoamps(cis);
-	return mv/1000000;
-}
-
-static ulong mantissa[16] =
-{ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, };
-
-static ulong exponent[8] =
-{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, };
 
-static ulong
-ttiming(Cisdat *cis, int scale)
-{
-	uchar unscaled;
-	ulong nanosecs;
-
-	if(readc(cis, &unscaled) != 1)
-		return 0;
-	nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;
-	nanosecs = nanosecs * vexp[scale];
-	return nanosecs;
-}
-
-static void
-timing(Cisdat *cis, Conftab *ct)
-{
-	uchar c, i;
-
-	if(readc(cis, &c) != 1)
-		return;
-	i = c&0x3;
-	if(i != 3)
-		ct->maxwait = ttiming(cis, i);		/* max wait */
-	i = (c>>2)&0x7;
-	if(i != 7)
-		ct->readywait = ttiming(cis, i);	/* max ready/busy wait */
-	i = (c>>5)&0x7;
-	if(i != 7)
-		ct->otherwait = ttiming(cis, i);	/* reserved wait */
-}
-
-static void
-iospaces(Cisdat *cis, Conftab *ct)
-{
-	uchar c;
-	int i, nio;
-
-	ct->nio = 0;
-	if(readc(cis, &c) != 1)
-		return;
-
-	ct->bit16 = ((c>>5)&3) >= 2;
-	if(!(c & 0x80)){
-		ct->io[0].start = 0;
-		ct->io[0].len = 1<<(c&0x1f);
-		ct->nio = 1;
-		return;
-	}
-
-	if(readc(cis, &c) != 1)
-		return;
-
-	nio = (c&0xf)+1;
-	for(i = 0; i < nio; i++){
-		ct->io[i].start = getlong(cis, (c>>4)&0x3);
-		ct->io[i].len = getlong(cis, (c>>6)&0x3)+1;
-	}
-	ct->nio = nio;
-}
-
-static void
-irq(Cisdat *cis, Conftab *ct)
-{
-	uchar c;
-
-	if(readc(cis, &c) != 1)
-		return;
-	ct->irqtype = c & 0xe0;
-	if(c & 0x10)
-		ct->irqs = getlong(cis, 2);
-	else
-		ct->irqs = 1<<(c&0xf);
-	ct->irqs &= 0xDEB8;		/* levels available to card */
-}
-
-static void
-memspace(Cisdat *cis, int asize, int lsize, int host)
-{
-	ulong haddress, address, len;
-
-	len = getlong(cis, lsize)*256;
-	address = getlong(cis, asize)*256;
-	USED(len, address);
-	if(host){
-		haddress = getlong(cis, asize)*256;
-		USED(haddress);
-	}
-}
-
-static void
-tentry(Slot *pp, Cisdat *cis, int )
-{
-	uchar c, i, feature;
-	Conftab *ct;
-
-	if(pp->nctab >= Maxctab)
-		return;
-	if(readc(cis, &c) != 1)
-		return;
-	ct = &pp->ctab[pp->nctab++];
-
-	/* copy from last default config */
-	if(pp->def)
-		*ct = *pp->def;
-
-	ct->index = c & 0x3f;
-
-	/* is this the new default? */
-	if(c & 0x40)
-		pp->def = ct;
+		/*  enable the device, enable address decode and
+		 *  irq enable.
+		 */
+		x |= Cfunc|Cdecode|Cirq;
 
-	/* memory wait specified? */
-	if(c & 0x80){
-		if(readc(cis, &i) != 1)
-			return;
-		if(i&0x80)
-			ct->memwait = 1;
+		p[0] = x;
+		//delay(5);
+		microdelay(40);
 	}
 
-	if(readc(cis, &feature) != 1)
-		return;
-	switch(feature&0x3){
-	case 1:
-		ct->vpp1 = ct->vpp2 = power(cis);
-		break;
-	case 2:
-		power(cis);
-		ct->vpp1 = ct->vpp2 = power(cis);
-		break;
-	case 3:
-		power(cis);
-		ct->vpp1 = power(cis);
-		ct->vpp2 = power(cis);
-		break;
-	default:
-		break;
-	}
-	if(feature&0x4)
-		timing(cis, ct);
-	if(feature&0x8)
-		iospaces(cis, ct);
-	if(feature&0x10)
-		irq(cis, ct);
-	switch((feature>>5)&0x3){
-	case 1:
-		memspace(cis, 0, 2, 0);
-		break;
-	case 2:
-		memspace(cis, 2, 2, 0);
-		break;
-	case 3:
-		if(readc(cis, &c) != 1)
-			return;
-		for(i = 0; i <= (c&0x7); i++)
-			memspace(cis, (c>>5)&0x3, (c>>3)&0x3, c&0x80);
-		break;
+	if(pp->cfg[0].cpresent & (1<<Riobase0)){
+		/* set up the iobase 0 */
+		p[Riobase0 << 1] = isa->port;
+		p[Riobase1 << 1] = isa->port >> 8;
 	}
-	pp->configed++;
-}
 
-static void
-tvers1(Slot *pp, Cisdat *cis, int )
-{
-	uchar c, major, minor;
-	int  i;
-
-	if(readc(cis, &major) != 1)
-		return;
-	if(readc(cis, &minor) != 1)
-		return;
-	for(i = 0; i < sizeof(pp->verstr)-1; i++){
-		if(readc(cis, &c) != 1)
-			return;
-		if(c == 0)
-			c = '\n';
-		if(c == 0xff)
-			break;
-		pp->verstr[i] = c;
-	}
-	pp->verstr[i] = 0;
+	if(pp->cfg[0].cpresent & (1<<Riosize))
+		p[Riosize << 1] = ct->io[0].len;
+	pcmunmap(slotno, m);
+	return 0;
 }

File diff suppressed because it is too large
+ 237 - 349
sys/src/boot/pc/devpccard.c


+ 30 - 3
sys/src/boot/pc/ether2114x.c

@@ -186,6 +186,8 @@ enum {					/* Variants */
 	Tulip3		= (0x0019<<16)|0x1011,
 	Pnic		= (0x0002<<16)|0x11AD,
 	Pnic2		= (0xC115<<16)|0x11AD,
+	CentaurP	= (0x0985<<16)|0x1317,
+	CentaurPcb	= (0x1985<<16)|0x1317,
 };
 
 typedef struct Ctlr Ctlr;
@@ -1372,6 +1374,13 @@ srom(Ctlr* ctlr)
 			ctlr->srom[20+i+1] = ctlr->srom[i];
 		}
 	}
+	if(ctlr->id == CentaurP || ctlr->id == CentaurPcb){
+		memmove(&ctlr->srom[20], leafpnic, sizeof(leafpnic));
+		for(i = 0; i < Eaddrlen; i += 2){
+			ctlr->srom[20+i] = ctlr->srom[8+i];
+			ctlr->srom[20+i+1] = ctlr->srom[8+i+1];
+		}
+	}
 
 	/*
 	 * Next, try to find the info leaf in the SROM for media detection.
@@ -1453,6 +1462,8 @@ srom(Ctlr* ctlr)
 	if(phy){
 		x = 0;
 		for(k = 0; k < nelem(ctlr->phy); k++){
+			if((ctlr->id == CentaurP || ctlr->id == CentaurPcb) && k != 1)
+				continue;
 			if((oui = miir(ctlr, k, 2)) == -1 || oui == 0)
 				continue;
 			if(DEBUG){
@@ -1497,10 +1508,12 @@ dec2114xpci(void)
 			pcicfgw32(p, 0x40, x);
 			/*FALLTHROUGH*/
 
-		case Pnic:			/* PNIC */
-		case Pnic2:			/* PNIC-II */
 		case Tulip0:			/* 21140 */
 		case Tulip1:			/* 21041 */
+		case Pnic:			/* PNIC */
+		case Pnic2:			/* PNIC-II */
+		case CentaurP:			/* ADMtek */
+		case CentaurPcb:		/* ADMtek CardBus */
 			break;
 		}
 
@@ -1531,13 +1544,27 @@ dec2114xpci(void)
 		switch(ctlr->id){
 		default:
 			break;
-
 		case Pnic:			/* PNIC */
 			/*
 			 * Turn off the jabber timer.
 			 */
 			csr32w(ctlr, 15, 0x00000001);
 			break;
+		case CentaurP:
+		case CentaurPcb:
+			/*
+			 * Nice - the register offsets change from *8 to *4
+			 * for CSR16 and up...
+			 * CSR25/26 give the MAC address read from the SROM.
+			 * Don't really need to use this other than as a check,
+			 * the SROM will be read in anyway so the value there
+			 * can be used directly.
+			 */
+			debug("csr25 %8.8luX csr26 %8.8luX\n",
+				inl(ctlr->port+0xA4), inl(ctlr->port+0xA8));
+			debug("phyidr1 %4.4luX phyidr2 %4.4luX\n",
+				inl(ctlr->port+0xBC), inl(ctlr->port+0xC0));
+			break;
 		}
 
 		if(ctlrhead != nil)

+ 1 - 1
sys/src/boot/pc/ether589.c

@@ -155,7 +155,7 @@ if(debug) print("none found\n");
 	if(memcmp(ea, ether->ea, 6) == 0 && strcmp(type, "3C562") == 0) {
 		if(debug)
 			print("read 562...");
-		if(pcmcistuple(slot, 0x88, ea, 6) == 6) {
+		if(pcmcistuple(slot, 0x88, -1, ea, 6) == 6) {
 			for(i = 0; i < 6; i += 2){
 				t = ea[i];
 				ea[i] = ea[i+1];

+ 0 - 2
sys/src/boot/pc/ether8169.c

@@ -22,8 +22,6 @@ typedef struct QLock { int r; } QLock;
 #define qlock(i)	while(0)
 #define qunlock(i)	while(0)
 #define iallocb		allocb
-extern void mb386(void);
-#define coherence()	mb386()
 #define iprint		print
 #define mallocalign(n, a, o, s)	ialloc((n), (a))
 

+ 0 - 5
sys/src/boot/pc/ether83815.c

@@ -300,11 +300,6 @@ enum {
 #define csr16r(c, r)	(ins((c)->port+(r)))
 #define csr16w(c, r, l)	(outs((c)->port+(r), (ulong)(l)))
 
-static void
-coherence(void)
-{
-}
-
 static void
 dumpcregs(Ctlr *ctlr)
 {

+ 218 - 177
sys/src/boot/pc/etherelnk3.c

@@ -49,7 +49,6 @@
 
 #include "etherif.h"
 
-#define coherence()
 #define XCVRDEBUG		if(0)print
 
 enum {
@@ -165,13 +164,12 @@ enum {						/* Window 0 - setup */
 	coaxAvailable9		= 0x1000,
 	auiAvailable9		= 0x2000,
 						/* EepromCommand bits */
-	_EepromReadRegister	= 0x0080,
-	_EepromRead8bRegister	= 0x0230,
+	EepromReadRegister	= 0x0080,
+	EepromReadOffRegister	= 0x00B0,
+	EepromRead8bRegister	= 0x0230,
 	EepromBusy		= 0x8000,
 };
 
-static int EepromReadRegister = _EepromReadRegister;
-
 #define EEPROMCMD(port, cmd, a)	outs((port)+EepromCommand, (cmd)|(a))
 #define EEPROMBUSY(port)	(ins((port)+EepromCommand) & EepromBusy)
 #define EEPROMDATA(port)	ins((port)+EepromData)
@@ -385,8 +383,8 @@ enum {						/* 3C90x extended register set */
 
 	updnLastFrag		= 0x80000000,	/* (dpd->len) */
 
-	Nup			= 32,
-	Ndn			= 64,
+	Nup			= 16,
+	Ndn			= 8,
 };
 
 /*
@@ -402,10 +400,18 @@ typedef struct Pd {
 	ulong	len;
 
 	Pd*	next;
-	void *vaddr;
+	void*	vaddr;
 } Pd;
 
-typedef struct {
+typedef struct Ctlr Ctlr;
+struct Ctlr {
+	int	port;
+	Pcidev*	pcidev;
+	int	irq;
+	Ctlr*	next;
+	int	active;
+	int	did;
+
 	Lock	wlock;				/* window access */
 
 	int	attached;
@@ -443,12 +449,19 @@ typedef struct {
 	ulong	dnqueued;
 
 	int	xcvr;				/* transceiver type */
+	int	eepromcmd;			/* EEPROM read command */
 	int	rxstatus9;			/* old-style RxStatus register */
 	int	rxearly;			/* RxEarlyThreshold */
 	int	ts;				/* threshold shift */
 	int	upenabled;
 	int	dnenabled;
-} Ctlr;
+
+	ulong	cbfnpa;				/* CardBus functions */
+	ulong*	cbfn;
+};
+
+static Ctlr* ctlrhead;
+static Ctlr* ctlrtail;
 
 static void
 init905(Ctlr* ctlr)
@@ -542,9 +555,9 @@ startdma(Ether* ether, ulong address)
 
 /* On the 575B and C, interrupts need to be acknowledged in CardBus memory space */
 static void
-intrack3c575(ulong *cbfns)
+intrackcb(ulong *cbfn)
 {
-	cbfns[1] = 0x8000;
+	cbfn[1] = 0x8000;
 }
 
 static void
@@ -562,7 +575,7 @@ attach(Ether* ether)
 
 	port = ether->port;
 
-	COMMAND(port, SetRxFilter, receiveIndividual|receiveBroadcast);
+	COMMAND(port, SetRxFilter, receiveIndividual/*|receiveBroadcast*/);
 	x = interruptMask;
 	if(ctlr->busmaster == 1)
 		x &= ~(rxEarly|rxComplete);
@@ -577,9 +590,11 @@ attach(Ether* ether)
 	COMMAND(port, RxEnable, 0);
 	COMMAND(port, TxEnable, 0);
 
-	if (ether->mem)
-		/* This must be a cardbus card.  Acknowledge the interrupt */
-		intrack3c575(KADDR(ether->mem));
+	/*
+	 * If this is a CardBus card, acknowledge any interrupts.
+	 */
+	if(ctlr->cbfn != nil)
+		intrackcb(ctlr->cbfn);
 		
 	/*
 	 * Prime the busmaster channel for receiving directly into a
@@ -1029,8 +1044,8 @@ interrupt(Ureg*, void* arg)
 			panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status);
 
 		COMMAND(port, AcknowledgeInterrupt, interruptLatch);
-		if (ether->mem) 
-			intrack3c575((ulong *)KADDR(ether->mem));
+		if(ctlr->cbfn != nil)
+			intrackcb(ctlr->cbfn);
 
 	}while((status = STATUS(port)) & (interruptMask|interruptLatch));
 
@@ -1046,7 +1061,6 @@ interrupt(Ureg*, void* arg)
 static void
 txrxreset(int port)
 {
-	COMMAND(port, TxReset, 0);
 	while(STATUS(port) & commandInProgress)
 		;
 	COMMAND(port, RxReset, 0);
@@ -1054,29 +1068,24 @@ txrxreset(int port)
 		;
 }
 
-typedef struct Adapter {
-	int		port;
-	int		irq;
-	int		tbdf;
-	ulong	cbfns;
-} Adapter;
-static Block* adapter;
-
-static void
-tcmadapter(int port, int irq, int tbdf, ulong cbfns)
+static Ctlr*
+tcmadapter(int port, int irq, Pcidev* pcidev)
 {
-	Block *bp;
-	Adapter *ap;
+	Ctlr *ctlr;
+
+	ctlr = malloc(sizeof(Ctlr));
+	ctlr->port = port;
+	ctlr->irq = irq;
+	ctlr->pcidev = pcidev;
+	ctlr->eepromcmd = EepromReadRegister;
 
-	bp = allocb(sizeof(Adapter));
-	ap = (Adapter*)bp->rp;
-	ap->port = port;
-	ap->irq = irq;
-	ap->tbdf = tbdf;
-	ap->cbfns = cbfns;
+	if(ctlrhead != nil)
+		ctlrtail->next = ctlr;
+	else
+		ctlrhead = ctlr;
+	ctlrtail = ctlr;
 
-	bp->next = adapter;
-	adapter = bp;
+	return ctlr;
 }
 
 /*
@@ -1216,7 +1225,7 @@ tcm509isa(void)
 		COMMAND(port, AcknowledgeInterrupt, 0xFF);
 
 		irq = (ins(port+ResourceConfig)>>12) & 0x0F;
-		tcmadapter(port, irq, BUSUNKNOWN, 0);
+		tcmadapter(port, irq, nil);
 	}
 }
 
@@ -1254,29 +1263,21 @@ tcm5XXeisa(void)
 		COMMAND(port, AcknowledgeInterrupt, 0xFF);
 
 		irq = (ins(port+ResourceConfig)>>12) & 0x0F;
-		tcmadapter(port, irq, BUSUNKNOWN, 0);
+		tcmadapter(port, irq, nil);
 	}
 }
 
 static void
-tcm59Xpci(Ether *ether)
+tcm59Xpci(void)
 {
 	Pcidev *p;
+	Ctlr *ctlr;
 	int irq, port;
-	ulong bar;
 
 	p = nil;
 	while(p = pcimatch(p, 0x10B7, 0)){
-		if (p->did == 0x5157) {
-			EepromReadRegister = _EepromRead8bRegister;
-			
-			/* Map the CardBus functions */
-			bar = pcicfgr32(p, PciBAR2);
-			print("ether#%d: CardBus functions at %.8luX\n", ether->ctlrno, bar & ~KZERO);
-		}
-		else
-			bar = 0;
-
+		if(p->ccrb != 0x02 || p->ccru != 0)
+			continue;
 		/*
 		 * Not prepared to deal with memory-mapped
 		 * devices yet.
@@ -1285,11 +1286,25 @@ tcm59Xpci(Ether *ether)
 			continue;
 		port = p->mem[0].bar & ~0x01;
 		irq = p->intl;
-		COMMAND(port, GlobalReset, 0);
-		while(STATUS(port) & commandInProgress)
-			;
 
-		tcmadapter(port, irq, p->tbdf, bar);
+		txrxreset(port);
+		COMMAND(port, AcknowledgeInterrupt, 0xFF);
+
+		ctlr = tcmadapter(port, irq, p);
+		switch(p->did){
+		default:
+			break;
+		case 0x5157:
+			ctlr->eepromcmd = EepromRead8bRegister;
+			ctlr->cbfnpa = p->mem[2].bar&~0x0F;
+			ctlr->cbfn = KADDR(ctlr->cbfnpa);
+			break;
+		case 0x6056:
+			ctlr->eepromcmd = EepromReadOffRegister;
+			ctlr->cbfnpa = p->mem[2].bar&~0x0F;
+			ctlr->cbfn = KADDR(ctlr->cbfnpa);
+			break;
+		}
 		pcisetbme(p);
 	}
 }
@@ -1301,32 +1316,33 @@ static char* tcmpcmcia[] = {
 	nil,
 };
 
-static int
+static Ctlr*
 tcm5XXpcmcia(Ether* ether)
 {
 	int i;
+	Ctlr *ctlr;
+
+	if(ether->type == nil)
+		return nil;
 
 	for(i = 0; tcmpcmcia[i] != nil; i++){
-		if(!cistrcmp(ether->type, tcmpcmcia[i])){
-			/*
-			 * No need for an ioalloc here, the 589 reset
-			 * code deals with it.
-			if(ioalloc(ether->port, 0x10, 0, "tcm5XXpcmcia") < 0)
-				return 0;
-			 */
-			return ether->port;
-		}
+		if(cistrcmp(ether->type, tcmpcmcia[i]))
+			continue;
+		ctlr = tcmadapter(ether->port, ether->irq, nil);
+		ctlr->active = 1;
+		return ctlr;
 	}
 
-	return 0;
+	return nil;
 }
 
 static void
-setxcvr(int port, int xcvr, int is9)
+setxcvr(Ctlr* ctlr, int xcvr)
 {
-	int x;
+	int port, x;
 
-	if(is9){
+	port = ctlr->port;
+	if(ctlr->rxstatus9){
 		COMMAND(port, SelectRegisterWindow, Wsetup);
 		x = ins(port+AddressConfig) & ~xcvrMask9;
 		x |= (xcvr>>20)<<14;
@@ -1425,7 +1441,7 @@ miir(int port, int phyad, int regad)
 	return data & 0xFFFF;
 }
 
-static void
+static int
 scanphy(int port)
 {
 	int i, x;
@@ -1437,7 +1453,10 @@ scanphy(int port)
 		x |= miir(port, i, 3)>>10;
 		XCVRDEBUG("phy%d: oui %uX reg1 %uX\n", i, x, miir(port, i, 1));
 		USED(x);
+
+		return i;
 	}
+	return 24;
 }
 
 #ifdef notdef
@@ -1470,10 +1489,9 @@ static struct {
 };
 
 static int
-autoselect(int port, int xcvr, int is9)
+autoselect(Ctlr* ctlr)
 {
-	int media, x;
-	USED(xcvr);
+	int media, port, x;
 
 	/*
 	 * Pathetic attempt at automatic media selection.
@@ -1481,7 +1499,8 @@ autoselect(int port, int xcvr, int is9)
 	 * cards operational.
 	 * It's a bonus if it works for anything else.
 	 */
-	if(is9){
+	port = ctlr->port;
+	if(ctlr->rxstatus9){
 		COMMAND(port, SelectRegisterWindow, Wsetup);
 		x = ins(port+ConfigControl);
 		media = 0;
@@ -1508,7 +1527,7 @@ autoselect(int port, int xcvr, int is9)
 		/*
 		 * Must have InternalConfig register.
 		 */
-		setxcvr(port, xcvr100BaseTX, is9);
+		setxcvr(ctlr, xcvr100BaseTX);
 
 		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
 		x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable);
@@ -1521,7 +1540,7 @@ autoselect(int port, int xcvr, int is9)
 	}
 
 	if(media & base10TAvailable){
-		setxcvr(port, xcvr10BaseT, is9);
+		setxcvr(ctlr, xcvr10BaseT);
 
 		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
 		x = ins(port+MediaStatus) & ~dcConverterEnabled;
@@ -1541,35 +1560,60 @@ autoselect(int port, int xcvr, int is9)
 }
 
 static int
-eepromdata(int port, int offset)
+eepromdata(Ctlr* ctlr, int offset)
 {
+	int port;
+
+	port = ctlr->port;
+
 	COMMAND(port, SelectRegisterWindow, Wsetup);
 	while(EEPROMBUSY(port))
 		;
-	EEPROMCMD(port, EepromReadRegister, offset);
+	EEPROMCMD(port, ctlr->eepromcmd, offset);
 	while(EEPROMBUSY(port))
 		;
 	return EEPROMDATA(port);
 }
 
+static void
+resetctlr(Ctlr *ctlr)
+{
+	int port, x;
+
+	port = ctlr->port;
+
+	txrxreset(port);
+	x = ins(port+ResetOp905B);
+	XCVRDEBUG("905[BC] reset ops 0x%uX\n", x);
+	x &= ~0x4010;
+	if(ctlr->did == 0x5157){
+		x |= 0x0010;			/* Invert LED */
+		outs(port+ResetOp905B, x);
+	}
+	if(ctlr->did == 0x6056){
+		x |= 0x4000;
+		outs(port+ResetOp905B, x);
+
+		COMMAND(port, SelectRegisterWindow, Wsetup);
+		outs(port, 0x0800);
+	}
+}
+
 int
 elnk3reset(Ether* ether)
 {
-	int anar, anlpar, phyaddr, phystat, timeo, xcvr;
-	int busmaster, did, i, j, port, rxearly, rxstatus9, x;
-	Block *bp, **bpp;
-	Adapter *ap;
-	uchar ea[Eaddrlen];
+	char *p;
 	Ctlr *ctlr;
+	uchar ea[Eaddrlen];
 	static int scandone;
-	char *p;
+	int anar, anlpar, i, j, phyaddr, phystat, port, timeo, x;
 
 	/*
 	 * Scan for adapter on PCI, EISA and finally
 	 * using the little ISA configuration dance.
 	 */
 	if(scandone == 0){
-		tcm59Xpci(ether);
+		tcm59Xpci();
 		tcm5XXeisa();
 		tcm509isa();
 		scandone = 1;
@@ -1579,74 +1623,78 @@ elnk3reset(Ether* ether)
 	 * Any adapter matches if no ether->port is supplied,
 	 * otherwise the ports must match.
 	 */
-	port = 0;
-	bpp = &adapter;
-	for(bp = *bpp; bp; bp = bp->next){
-		ap = (Adapter*)bp->rp;
-		if(ether->port == 0 || ether->port == ap->port){
-			port = ap->port;
-			ether->irq = ap->irq;
-			ether->tbdf = ap->tbdf;
-			ether->mem = ap->cbfns;	/* Misuse the mem ref for the cardbus functions */
-			*bpp = bp->next;
-			freeb(bp);
+	for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
+		if(ctlr->active)
+			continue;
+		if(ether->port == 0 || ether->port == ctlr->port){
+			ctlr->active = 1;
 			break;
 		}
-		bpp = &bp->next;
 	}
-	if(port == 0 && (port = tcm5XXpcmcia(ether)) == 0)
+	if(ctlr == nil && (ctlr = tcm5XXpcmcia(ether)) == 0)
 		return -1;
 
+	ether->ctlr = ctlr;
+	port = ctlr->port;
+	ether->port = port;
+	ether->irq = ctlr->irq;
+	if(ctlr->pcidev != nil)
+		ether->tbdf = ctlr->pcidev->tbdf;
+	else
+		ether->tbdf = BUSUNKNOWN;
+
 	/*
 	 * Read the DeviceID from the EEPROM, it's at offset 0x03,
 	 * and do something depending on capabilities.
 	 */
-	switch(did = eepromdata(port, 0x03)){
-
-	case 0x9000:
-	case 0x9001:
-	case 0x9005:
-	case 0x9050:
-	case 0x9051:
-	case 0x9055:
-	case 0x4500:		/* 3C450 HomePNA Tornado */
+	switch(ctlr->did = eepromdata(ctlr, 0x03)){
+	case 0x5157:		/* 3C575 Cyclone */
 	case 0x6056:
-	case 0x9200:		/* 3C905C-TX */
+		/*FALLTHROUGH*/
+	case 0x4500:		/* 3C450 HomePNA Tornado */
 	case 0x7646:		/* 3CSOHO100-TX */
-	case 0x5157:		/* 3C575 Cyclone */
+	case 0x9055:		/* 3C905B-TX */
+	case 0x9200:		/* 3C905C-TX */
+	case 0x9201:		/* 3C920 */
+		/*FALLTHROUGH*/
+	case 0x9000:		/* 3C900-TPO */
+	case 0x9001:		/* 3C900-COMBO */
+	case 0x9005:		/* 3C900B-COMBO */
+	case 0x9050:		/* 3C905-TX */
+	case 0x9051:		/* 3C905-T4 */
 		if(BUSTYPE(ether->tbdf) != BusPCI)
 			goto buggery;
-		busmaster = 2;
+		ctlr->busmaster = 2;
 		goto vortex;
-
-	case 0x5900:
-	case 0x5920:
-	case 0x5950:
-	case 0x5951:
-	case 0x5952:
-	case 0x5970:
-	case 0x5971:
-	case 0x5972:
-		busmaster = 1;
+	case 0x5900:		/* 3C590-[TP|COMBO|TPO] */
+	case 0x5920:		/* 3C592-[TP|COMBO|TPO] */
+	case 0x5950:		/* 3C595-TX */
+	case 0x5951:		/* 3C595-T4 */
+	case 0x5952:		/* 3C595-MII */
+	case 0x5970:		/* 3C597-TX */
+	case 0x5971:		/* 3C597-T4 */
+	case 0x5972:		/* 3C597-MII */
+		ctlr->busmaster = 1;
 	vortex:
 		COMMAND(port, SelectRegisterWindow, Wfifo);
-		xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask);
-		rxearly = 8188;
-		rxstatus9 = 0;
+		ctlr->xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask);
+		ctlr->rxearly = 8188;
+		ctlr->rxstatus9 = 0;
 		break;
-
 	buggery:
 	default:
-		busmaster = 0;
+		ctlr->busmaster = 0;
 		COMMAND(port, SelectRegisterWindow, Wsetup);
 		x = ins(port+AddressConfig);
-		xcvr = ((x & xcvrMask9)>>14)<<20;
+		ctlr->xcvr = ((x & xcvrMask9)>>14)<<20;
 		if(x & autoSelect9)
-			xcvr |= autoSelect;
-		rxearly = 2044;
-		rxstatus9 = 1;
+			ctlr->xcvr |= autoSelect;
+		ctlr->rxearly = 2044;
+		ctlr->rxstatus9 = 1;
 		break;
 	}
+	if(ctlr->rxearly >= 2048)
+		ctlr->ts = 2;
 
 	/*
 	 * Check if the adapter's station address is to be overridden.
@@ -1657,7 +1705,7 @@ elnk3reset(Ether* ether)
 	memset(ea, 0, Eaddrlen);
 	if(memcmp(ea, ether->ea, Eaddrlen) == 0){
 		for(i = 0; i < Eaddrlen/2; i++){
-			x = eepromdata(port, i);
+			x = eepromdata(ctlr, i);
 			ether->ea[2*i] = x>>8;
 			ether->ea[2*i+1] = x;
 		}
@@ -1672,7 +1720,7 @@ elnk3reset(Ether* ether)
 	 * busmastering can be used. Due to bugs in the first revision
 	 * of the 3C59[05], don't use busmastering at 10Mbps.
 	 */
-	XCVRDEBUG("reset: xcvr %uX\n", xcvr);
+	XCVRDEBUG("reset: xcvr %uX\n", ctlr->xcvr);
 
 	/*
 	 * Allow user to specify desired media in plan9.ini
@@ -1683,38 +1731,41 @@ elnk3reset(Ether* ether)
 		p = ether->opt[i]+6;
 		for(j = 0; j < nelem(media); j++)
 			if(cistrcmp(p, media[j].name) == 0)
-				xcvr = media[j].xcvr;
+				ctlr->xcvr = media[j].xcvr;
 	}
 	
 	/*
 	 * forgive me, but i am weak
 	 */
-	if(did == 0x9055 || did == 0x7646 || did == 0x9200 || did == 0x5157){
-		xcvr = xcvrMii;
-		txrxreset(port);
-		XCVRDEBUG("905[BC] reset ops 0x%uX\n", ins(port+ResetOp905B));
-
-		if (did == 0x5157) {
-			ushort reset_opts;
-
-			COMMAND(port, SelectRegisterWindow, Wstation);
-			reset_opts = ins(port + ResetOp905B);
-			reset_opts |= 0x0010;		/* Invert LED */
-			outs(port + ResetOp905B, reset_opts);
-		}
+	switch(ctlr->did){
+	default:
+		if(ctlr->xcvr & autoSelect)
+			ctlr->xcvr = autoselect(ctlr);
+		break;
+	case 0x5157:
+	case 0x6056:
+	case 0x4500:
+	case 0x7646:
+	case 0x9055:
+	case 0x9200:
+	case 0x9201:
+		ctlr->xcvr = xcvrMii;
+		resetctlr(ctlr);
+		break;
 	}
-	else if(xcvr & autoSelect)
-		xcvr = autoselect(port, xcvr, rxstatus9);
-	XCVRDEBUG("autoselect returns: xcvr %uX, did 0x%uX\n", xcvr, did);
-
-	switch(xcvr){
+	XCVRDEBUG("xcvr selected: %uX, did 0x%uX\n", ctlr->xcvr, ctlr->did);
 
+	switch(ctlr->xcvr){
 	case xcvrMii:
 		/*
 		 * Quick hack.
-		scanphy(port);
 		 */
-		phyaddr = (did == 0x5157)? 0: 24;
+		if(ctlr->did == 0x5157)
+			phyaddr = 0;
+		else if(ctlr->did == 0x6056)
+			phyaddr = scanphy(port);
+		else
+			phyaddr = 24;
 		for(i = 0; i < 7; i++)
 			XCVRDEBUG(" %2.2uX", miir(port, phyaddr, i));
 			XCVRDEBUG("\n");
@@ -1746,13 +1797,14 @@ elnk3reset(Ether* ether)
 		}
 		XCVRDEBUG("mii anar: %uX\n", anar);
 		if(anar & 0x0100){		/* 100BASE-TXFD */
+			//ether->mbps = 100;
 			setfullduplex(port);
 		}
 		else if(anar & 0x0200){		/* 100BASE-T4 */
 			/* nothing to do */
 		}
 		else if(anar & 0x0080){		/* 100BASE-TX */
-			/* nothing to do */;
+			//ether->mbps = 100;
 		}
 		else if(anar & 0x0040)		/* 10BASE-TFD */
 			setfullduplex(port);
@@ -1771,6 +1823,9 @@ elnk3reset(Ether* ether)
 		x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable);
 		x |= linkBeatEnable;
 		outs(port+MediaStatus, x);
+
+		//if(x & dataRate100)
+		//	ether->mbps = 100;
 		break;
 
 	case xcvr10BaseT:
@@ -1783,8 +1838,8 @@ elnk3reset(Ether* ether)
 		x |= linkBeatEnable|jabberGuardEnable;
 		outs(port+MediaStatus, x);
 
-		if((did & 0xFF00) == 0x5900)
-			busmaster = 0;
+		if((ctlr->did & 0xFF00) == 0x5900)
+			ctlr->busmaster = 0;
 		break;
 
 	case xcvr10Base2:
@@ -1809,7 +1864,7 @@ elnk3reset(Ether* ether)
 	 * Clear out any lingering Tx status.
 	 */
 	COMMAND(port, SelectRegisterWindow, Wop);
-	if(busmaster == 2)
+	if(ctlr->busmaster == 2)
 		x = port+TxStatus905;
 	else
 		x = port+TxStatus;
@@ -1817,27 +1872,14 @@ elnk3reset(Ether* ether)
 		outb(x, 0);
 
 	/*
-	 * Allocate a controller structure, clear out the
-	 * adapter statistics, clear the statistics logged into ctlr
-	 * and enable statistics collection. Xcvr is needed in order
-	 * to collect the BadSSD statistics.
+	 * Clear out the
+	 * adapter statistics, clear the statistics logged into ctlr.
 	 */
-	ether->ctlr = malloc(sizeof(Ctlr));
-	ctlr = ether->ctlr;
-
 	ilock(&ctlr->wlock);
-	ctlr->xcvr = xcvr;
 	statistics(ether);
 	memset(ctlr->stats, 0, sizeof(ctlr->stats));
 
-	ctlr->busmaster = busmaster;
-	ctlr->xcvr = xcvr;
-	ctlr->rxstatus9 = rxstatus9;
-	ctlr->rxearly = rxearly;
-	if(rxearly >= 2048)
-		ctlr->ts = 2;
-
-	COMMAND(port, StatisticsEnable, 0);
+	//COMMAND(port, StatisticsEnable, 0);
 
 	/*
 	 * Allocate any receive buffers.
@@ -1855,7 +1897,7 @@ elnk3reset(Ether* ether)
 		 * until the whole packet has been received.
 		 */
 		ctlr->upenabled = 1;
-		x = eepromdata(port, 0x0F);
+		x = eepromdata(ctlr, 0x0F);
 		if(!(x & 0x01))
 			outl(port+PktStatus, upRxEarlyEnable);
 
@@ -1872,14 +1914,13 @@ elnk3reset(Ether* ether)
 	 */
 	ctlr->txthreshold = ETHERMAXTU/2;
 	COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts);
-	COMMAND(port, SetRxEarlyThresh, rxearly>>ctlr->ts);
+	COMMAND(port, SetRxEarlyThresh, ctlr->rxearly>>ctlr->ts);
 
 	iunlock(&ctlr->wlock);
 
 	/*
 	 * Linkage to the generic ethernet driver.
 	 */
-	ether->port = port;
 	ether->attach = attach;
 	ether->transmit = transmit;
 	ether->interrupt = interrupt;

+ 0 - 1
sys/src/boot/pc/etherrhine.c

@@ -18,7 +18,6 @@
 typedef struct QLock { int r; } QLock;
 #define qlock(i)	while(0)
 #define qunlock(i)	while(0)
-#define coherence()
 #define iprint		print
 
 #include "etherif.h"

+ 7 - 1
sys/src/boot/pc/fns.h

@@ -15,6 +15,7 @@ int	cistrncmp(char*, char*, int);
 void	changeconf(char*, ...);
 void	checkalarms(void);
 void	clockinit(void);
+#define coherence()	mb386()
 void	consdrain(void);
 void	consinit(char*, char*);
 void	consputs(char*, int);
@@ -53,11 +54,14 @@ ulong	inl(int);
 void	insb(int, void*, int);
 void	inss(int, void*, int);
 void	insl(int, void*, int);
+#define ioalloc(addr, len, align, name)	(addr)
+#define iofree(addr)
 void	iunlock(Lock*);
 int	isaconfig(char*, int, ISAConf*);
 void	kbdinit(void);
 void	kbdchar(int);
 void	machinit(void);
+void	mb386(void);
 void	meminit(ulong);
 void	microdelay(int);
 void	mmuinit(void);
@@ -83,7 +87,9 @@ uchar	pciintl(Pcidev *);
 uchar	pciipin(Pcidev *, uchar);
 void	pcireset(void);
 void	pcisetbme(Pcidev*);
-int	pcmcistuple(int, int, void*, int);
+void	pcmcisread(PCMslot*);
+int	pcmcistuple(int, int, int, void*, int);
+PCMmap*	pcmmap(int, ulong, int, int);
 int	pcmspecial(char*, ISAConf*);
 void	pcmspecialclose(int);
 void	pcmunmap(int, PCMmap*);

+ 71 - 3
sys/src/boot/pc/io.h

@@ -133,7 +133,7 @@ enum {					/* type 2 pre-defined header */
 	PciCBILR0	= 0x30,		/* I/O limit */
 	PciCBIBR1	= 0x34,		/* I/O base */
 	PciCBILR1	= 0x38,		/* I/O limit */
-	PciCBBCTL	= 0x3E,		/* Bridhe control */
+	PciCBBCTL	= 0x3E,		/* Bridge control */
 	PciCBSVID	= 0x40,		/* subsystem vendor ID */
 	PciCBSID	= 0x42,		/* subsystem ID */
 	PciCBLMBAR	= 0x44,		/* legacy mode base address */
@@ -153,10 +153,14 @@ typedef struct Pcidev {
 	ushort	vid;			/* vendor ID */
 	ushort	did;			/* device ID */
 
+	ushort	pcr;
+
 	uchar	rid;
 	uchar	ccrp;
 	uchar	ccru;
 	uchar	ccrb;
+	uchar	cls;
+	uchar	ltr;
 
 	struct {
 		ulong	bar;		/* base address */
@@ -170,14 +174,15 @@ typedef struct Pcidev {
 	uchar	intl;			/* interrupt line */
 
 	Pcidev*	list;
-	Pcidev*	bridge;			/* down a bus */
 	Pcidev*	link;			/* next device on this bno */
+
+	Pcidev*	bridge;			/* down a bus */
 	struct {
 		ulong	bar;
 		int	size;
 	} ioa, mema;
 
-	ulong	pcr;
+	int	pmrb;			/* power management register block */
 };
 
 #define PCIWINDOW	0
@@ -188,6 +193,9 @@ typedef struct Pcidev {
 /*
  * PCMCIA support code.
  */
+typedef struct PCMslot		PCMslot;
+typedef struct PCMconftab	PCMconftab;
+
 /*
  * Map between ISA memory space and PCMCIA card memory space.
  */
@@ -199,3 +207,63 @@ struct PCMmap {
 	int	attr;			/* attribute memory */
 	int	ref;
 };
+
+/* configuration table entry */
+struct PCMconftab
+{
+	int	index;
+	ushort	irqs;		/* legal irqs */
+	uchar	irqtype;
+	uchar	bit16;		/* true for 16 bit access */
+	struct {
+		ulong	start;
+		ulong	len;
+	} io[16];
+	int	nio;
+	uchar	vpp1;
+	uchar	vpp2;
+	uchar	memwait;
+	ulong	maxwait;
+	ulong	readywait;
+	ulong	otherwait;
+};
+
+/* a card slot */
+struct PCMslot
+{
+	Lock;
+	int	ref;
+
+	void	*cp;		/* controller for this slot */
+	long	memlen;		/* memory length */
+	uchar	base;		/* index register base */
+	uchar	slotno;		/* slot number */
+
+	/* status */
+	uchar	special;	/* in use for a special device */
+	uchar	already;	/* already inited */
+	uchar	occupied;
+	uchar	battery;
+	uchar	wrprot;
+	uchar	powered;
+	uchar	configed;
+	uchar	enabled;
+	uchar	busy;
+
+	/* cis info */
+	ulong	msec;		/* time of last slotinfo call */
+	char	verstr[512];	/* version string */
+	int	ncfg;		/* number of configurations */
+	struct {
+		ushort	cpresent;	/* config registers present */
+		ulong	caddr;		/* relative address of config registers */
+	} cfg[8];
+	int	nctab;		/* number of config table entries */
+	PCMconftab	ctab[8];
+	PCMconftab	*def;	/* default conftab */
+
+	/* memory maps */
+	Lock	mlock;		/* lock down the maps */
+	int	time;
+	PCMmap	mmap[4];	/* maps, last is always for the kernel */
+};

+ 4 - 3
sys/src/boot/pc/mkfile

@@ -33,9 +33,10 @@ LOAD=\
 	8250.$O\
 	apm.$O\
 	boot.$O\
-	devpccard.$O\
+	cis.$O\
 	conf.$O\
 	devi82365.$O\
+	devpccard.$O\
 	devsd.$O\
 	inflate.$O\
 	load.$O\
@@ -166,8 +167,8 @@ install:V:
 		mk $MKFLAGS $i.install
 
 %.install:V:	$BIN/%
-	#import lookout / /n/lookout
-	#cp $prereq /n/lookout/$prereq
+	import lookout / /n/lookout
+	cp $prereq /n/lookout/$prereq
 
 $BIN/%:	%
 	cp $stem $BIN/$stem

+ 17 - 12
sys/src/boot/pc/sd53c8xx.c

@@ -1869,23 +1869,28 @@ static Variant variant[] = {
 static int
 xfunc(Controller *c, enum na_external x, unsigned long *v)
 {
-	switch (x)
-	{
+	switch (x) {
+	default:
+		print("xfunc: can't find external %d\n", x);
+		return 0;
 	case X_scsi_id_buf:
-		*v = offsetof(Dsa, scsi_id_buf[0]); return 1;
+		*v = offsetof(Dsa, scsi_id_buf[0]);
+		break;
 	case X_msg_out_buf:
-		*v = offsetof(Dsa, msg_out_buf); return 1;
+		*v = offsetof(Dsa, msg_out_buf);
+		break;
 	case X_cmd_buf:
-		*v = offsetof(Dsa, cmd_buf); return 1;
+		*v = offsetof(Dsa, cmd_buf);
+		break;
 	case X_data_buf:
-		*v = offsetof(Dsa, data_buf); return 1;
+		*v = offsetof(Dsa, data_buf);
+		break;
 	case X_status_buf:
-		*v = offsetof(Dsa, status_buf); return 1;
+		*v = offsetof(Dsa, status_buf);
+		break;
 	case X_dsa_head:
-		*v = DMASEG(&c->dsalist.head[0]); return 1;
-	default:
-		print("xfunc: can't find external %d\n", x);
-		return 0;
+		*v = DMASEG(&c->dsalist.head[0]);
+		break;
 	}
 	return 1;
 }
@@ -1960,7 +1965,7 @@ sympnp(void)
 		}
 		if(v >= &variant[nelem(variant)])
 			continue;
-		print("sd53c8xx: %s rev. 0x%2.2x intr=%d command=%4.4luX\n",
+		print("sd53c8xx: %s rev. 0x%2.2x intr=%d command=%4.4uX\n",
 			v->name, p->rid, p->intl, p->pcr);
 
 		regpa = p->mem[1].bar;

+ 1 - 1
sys/src/boot/pc/sdata.c

@@ -1465,7 +1465,7 @@ atapnp(void)
 		case (0x4D69<<16)|0x105A:	/* Promise Ultra/133 TX2 */
 		case (0x3373<<16)|0x105A:	/* Promise 20378 RAID */
 		case (0x3149<<16)|0x1106:	/* VIA VT8237 SATA/RAID */
-		case (0x3112<<16)|0x1095:   	/* SiL 3112 SATA (DMA busted?) */
+		case (0x3112<<16)|0x1095:	/* SiL 3112 SATA (DMA busted?) */
 		case (0x3114<<16)|0x1095:	/* SiL 3114 SATA/RAID */
 			pi = 0x85;
 			break;

+ 0 - 2
sys/src/boot/pc/sdmylex.c

@@ -26,8 +26,6 @@ typedef struct QLock{ int r; } QLock;
 typedef struct Rendez{ int r; } Rendez;
 #define	intrenable(irq, f, c, tbdf, name)	setvec(VectorPIC+(irq), f, c);\
 						USED(tbdf);
-#define ioalloc(p, b, c, d)	(1)
-#define iofree(p)
 
 #define K2BPA(va, tbdf)	PADDR(va)
 #define BPA2K(pa, tbdf)	KADDR(pa)

+ 4 - 4
sys/src/boot/pc/sdscsi.c

@@ -133,7 +133,7 @@ scsirio(SDreq* r)
 // cgascreenputs("C", 1);
 	switch(r->unit->dev->ifc->rio(r)){
 	default:
-		return -1;
+		break;
 	case SDcheck:
 		if(!(r->flags & SDvalidsense))
 			return -1;
@@ -151,7 +151,7 @@ scsirio(SDreq* r)
 				return 2;
 			if(r->sense[12] == 0x29)
 				return 2;
-			return -1;
+			break;
 		case 0x02:		/* not ready */
 			/*
 			 * If no medium present, bail out.
@@ -166,9 +166,9 @@ scsirio(SDreq* r)
 			scsitest(r);
 			return 2;
 		default:
-			return -1;
+			break;
 		}
-		return -1;
+		break;
 	case SDok:
 		return 0;
 	}

+ 2 - 2
sys/src/boot/pc/trap.c

@@ -182,7 +182,7 @@ trapinit(void)
 	 */
 	outb(Int0ctl, Icw1|0x01);	/* ICW1 - edge triggered, master,
 					   ICW4 will be sent */
-	outb(Int0aux, VectorPIC);		/* ICW2 - interrupt vector offset */
+	outb(Int0aux, VectorPIC);	/* ICW2 - interrupt vector offset */
 	outb(Int0aux, 0x04);		/* ICW3 - have slave on level 2 */
 	outb(Int0aux, 0x01);		/* ICW4 - 8086 mode, not buffered */
 
@@ -194,7 +194,7 @@ trapinit(void)
 	 */
 	outb(Int1ctl, Icw1|0x01);	/* ICW1 - edge triggered, master,
 					   ICW4 will be sent */
-	outb(Int1aux, VectorPIC+8);		/* ICW2 - interrupt vector offset */
+	outb(Int1aux, VectorPIC+8);	/* ICW2 - interrupt vector offset */
 	outb(Int1aux, 0x02);		/* ICW3 - I am a slave on level 2 */
 	outb(Int1aux, 0x01);		/* ICW4 - 8086 mode, not buffered */
 	outb(Int1aux, int1mask);

+ 922 - 0
sys/src/cmd/ip/snoopy/dns.c

@@ -0,0 +1,922 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include "dat.h"
+#include "protos.h"
+#include "../../ndb/dns.h"
+
+/* names of RR types - /sys/src/cmd/ndb/dn.c:/rrtname */
+char *rrtname[] =
+{
+[Ta]		"ip",
+[Tns]		"ns",
+[Tmd]		"md",
+[Tmf]		"mf",
+[Tcname]	"cname",
+[Tsoa]		"soa",
+[Tmb]		"mb",
+[Tmg]		"mg",
+[Tmr]		"mr",
+[Tnull]		"null",
+[Twks]		"wks",
+[Tptr]		"ptr",
+[Thinfo]	"hinfo",
+[Tminfo]	"minfo",
+[Tmx]		"mx",
+[Ttxt]		"txt",
+[Trp]		"rp",
+[Tafsdb]	"afsdb",
+[Tx25]		"x.25",
+[Tisdn]		"isdn",
+[Trt]		"rt",
+[Tnsap]		"nsap",
+[Tnsapptr]	"nsap-ptr",
+[Tsig]		"sig",
+[Tkey]		"key",
+[Tpx]		"px",
+[Tgpos]		"gpos",
+[Taaaa]		"ipv6",
+[Tloc]		"loc",
+[Tnxt]		"nxt",
+[Teid]		"eid",
+[Tnimloc]	"nimrod",
+[Tsrv]		"srv",
+[Tatma]		"atma",
+[Tnaptr]	"naptr",
+[Tkx]		"kx",
+[Tcert]		"cert",
+[Ta6]		"a6",
+[Tdname]	"dname",
+[Tsink]		"sink",
+[Topt]		"opt",
+[Tapl]		"apl",
+[Tds]		"ds",
+[Tsshfp]	"sshfp",
+[Tipseckey]	"ipseckey",
+[Trrsig]	"rrsig",
+[Tnsec]		"nsec",
+[Tdnskey]	"dnskey",
+[Tspf]		"spf",
+[Tuinfo]	"uinfo",
+[Tuid]		"uid",
+[Tgid]		"gid",
+[Tunspec]	"unspec",
+[Ttkey]		"tkey",
+[Ttsig]		"tsig",
+[Tixfr]		"ixfr",
+[Taxfr]		"axfr",
+[Tmailb]	"mailb",
+[Tmaila]	"maila",
+[Tall]		"all",
+		0,
+};
+static char*
+rrtypestr(int t)
+{
+	char buf[20];
+
+	if(t >= 0 && t < nelem(rrtname) && rrtname[t])
+		return rrtname[t];
+	snprint(buf, sizeof buf, "type%d", t);
+	return buf;
+}
+
+static void
+fmtrr(Msg *m, RR **rrp, int quest)
+{
+	Txt *t;
+	RR *rr;
+
+	rr = *rrp;
+	if(rr == nil)
+		return;
+	*rrp = rr->next;
+
+	m->p = seprint(m->p, m->e, "%s name=%s ttl=%lud",
+		rrtypestr(rr->type),
+		rr->owner->name, rr->ttl);
+	if(!quest)
+	switch(rr->type){
+	default:
+		break;
+	case Thinfo:
+		m->p = seprint(m->p, m->e, " cpu=%s os=%s", rr->cpu->name, rr->os->name);
+		break;
+	case Tcname:
+	case Tmb:
+	case Tmd:
+	case Tmf:
+	case Tns:
+		m->p = seprint(m->p, m->e, " host=%s", rr->host->name);
+		break;
+	case Tmg:
+	case Tmr:
+		m->p = seprint(m->p, m->e, " mb=%s", rr->mb->name);
+		break;
+	case Tminfo:
+		m->p = seprint(m->p, m->e, " rmb=%s", rr->rmb->name);
+		m->p = seprint(m->p, m->e, " mb=%s", rr->mb->name);
+		break;
+	case Tmx:
+		m->p = seprint(m->p, m->e, " pref=%lud", rr->pref);
+		m->p = seprint(m->p, m->e, " host=%s", rr->host->name);
+		break;
+	case Ta:
+	case Taaaa:
+		m->p = seprint(m->p, m->e, " ip=%s", rr->ip->name);
+		break;
+	case Tptr:
+		m->p = seprint(m->p, m->e, " ptr=%s", rr->ptr->name);
+		break;
+	case Tsoa:
+		m->p = seprint(m->p, m->e, " host=%s", rr->host->name);
+		m->p = seprint(m->p, m->e, " rmb=%s", rr->rmb->name);
+		m->p = seprint(m->p, m->e, " soa.serial=%lud", rr->soa->serial);
+		m->p = seprint(m->p, m->e, " soa.refresh=%lud", rr->soa->refresh);
+		m->p = seprint(m->p, m->e, " soa.retry=%lud", rr->soa->retry);
+		m->p = seprint(m->p, m->e, " soa.expire=%lud", rr->soa->expire);
+		m->p = seprint(m->p, m->e, " soa.minttl=%lud", rr->soa->minttl);
+		break;
+	case Ttxt:
+		for(t=rr->txt; t; t=t->next)
+			m->p = seprint(m->p, m->e, " txt=%q", t->p);
+		break;
+	case Tnull:
+		m->p = seprint(m->p, m->e, " null=%.*H", rr->null->dlen, rr->null->data);
+		break;
+	case Trp:
+		m->p = seprint(m->p, m->e, " rmb=%s", rr->rmb->name);
+		m->p = seprint(m->p, m->e, " rp=%s", rr->rp->name);
+		break;
+	case Tkey:
+		m->p = seprint(m->p, m->e, " flags=%d proto=%d alg=%d data=%.*H", rr->key->flags, rr->key->proto, rr->key->alg, rr->key->dlen, rr->key->data);
+		break;
+	case Tsig:
+		m->p = seprint(m->p, m->e, " type=%d alg=%d labels=%d ttl=%lud exp=%lud incep=%lud tag=%d signer=%s data=%.*H",
+			rr->sig->type, rr->sig->alg, rr->sig->labels,
+			rr->sig->ttl, rr->sig->exp, rr->sig->incep, rr->sig->tag,
+			rr->sig->signer->name, rr->sig->dlen, rr->sig->data);
+		break;
+	case Tcert:
+		m->p = seprint(m->p, m->e, " type=%d tag=%d alg=%d data=%.*H", rr->cert->type, rr->cert->tag, rr->cert->alg, rr->cert->dlen, rr->cert->data);
+		break;
+	}
+	rrfree(rr);
+}
+
+void freealldn(void);
+static Proto dnsqd, dnsan, dnsns, dnsar;
+
+static void donext(Msg*);
+static DNSmsg dm;
+
+static int
+p_seprint(Msg *m)
+{
+	char *e;
+
+	if((e = convM2DNS(m->ps, m->pe-m->ps, &dm)) != nil){
+		m->p = seprint(m->p, m->e, "error: %s", e);
+		return 0;
+	}
+	m->p = seprint(m->p, m->e, "id=%d flags=%#ux", dm.id, dm.flags);
+	donext(m);
+	return 0;
+}
+
+static void
+donext(Msg *m)
+{
+	if(dm.qd)
+		m->pr = &dnsqd;
+	else if(dm.an)
+		m->pr = &dnsan;
+	else if(dm.ns)
+		m->pr = &dnsns;
+	else if(dm.ar)
+		m->pr = &dnsar;
+	else{
+		freealldn();
+		memset(&dm, 0, sizeof dm);
+		m->pr = nil;
+	}
+}
+
+static int
+p_seprintqd(Msg *m)
+{
+	fmtrr(m, &dm.qd, 1);
+	donext(m);
+	return 0;
+}
+
+static int
+p_seprintan(Msg *m)
+{
+	fmtrr(m, &dm.an, 0);
+	donext(m);
+	return 0;
+}
+
+static int
+p_seprintns(Msg *m)
+{
+	fmtrr(m, &dm.ns, 1);
+	donext(m);
+	return 0;
+}
+
+static int
+p_seprintar(Msg *m)
+{
+	fmtrr(m, &dm.ar, 1);
+	donext(m);
+	return 0;
+}
+
+Proto dns =
+{
+	"dns",
+	nil,
+	nil,
+	p_seprint,
+	nil,
+	nil,
+	nil,
+	defaultframer,
+};
+
+static Proto dnsqd =
+{
+	"dns.qd",
+	nil,
+	nil,
+	p_seprintqd,
+	nil,
+	nil,
+	nil,
+	defaultframer,
+};
+
+static Proto dnsan =
+{
+	"dns.an",
+	nil,
+	nil,
+	p_seprintan,
+	nil,
+	nil,
+	nil,
+	defaultframer,
+};
+
+static Proto dnsns =
+{
+	"dns.ns",
+	nil,
+	nil,
+	p_seprintns,
+	nil,
+	nil,
+	nil,
+	defaultframer,
+};
+
+static Proto dnsar =
+{
+	"dns.ar",
+	nil,
+	nil,
+	p_seprintar,
+	nil,
+	nil,
+	nil,
+	defaultframer,
+};
+
+
+void*
+emalloc(int n)
+{
+	void *v;
+
+	v = mallocz(n, 1);
+	if(v == nil)
+		sysfatal("out of memory");
+	return v;
+}
+
+char*
+estrdup(char *s)
+{
+	s = strdup(s);
+	if(s == nil)
+		sysfatal("out of memory");
+	return s;
+}
+
+DN *alldn;
+
+DN*
+dnlookup(char *name, int class, int)
+{
+	DN *dn;
+
+	dn = emalloc(sizeof *dn);
+	dn->name = estrdup(name);
+	dn->class = class;
+	dn->magic = DNmagic;
+	dn->next = alldn;
+	alldn = dn;
+	return dn;
+}
+
+void
+freealldn(void)
+{
+	DN *dn;
+
+	while(dn = alldn){
+		alldn = dn->next;
+		free(dn->name);
+		free(dn);
+	}
+}
+
+
+#define now 0
+
+/*************************************************
+ Everything below here is copied from /sys/src/cmd/ndb
+ without modification and can be recopied to update.
+ First parts from dn.c, then all of convM2DNS.c.
+*/
+
+/*
+ *  free a list of resource records and any related structs
+ */
+void
+rrfreelist(RR *rp)
+{
+	RR *next;
+
+	for(; rp; rp = next){
+		next = rp->next;
+		rrfree(rp);
+	}
+}
+void
+freeserverlist(Server *s)
+{
+	Server *next;
+
+	for(; s != nil; s = next){
+		next = s->next;
+		free(s);
+	}
+}
+
+/*
+ *  allocate a resource record of a given type
+ */
+RR*
+rralloc(int type)
+{
+	RR *rp;
+
+	rp = emalloc(sizeof(*rp));
+	rp->magic = RRmagic;
+	rp->pc = getcallerpc(&type);
+	rp->type = type;
+	switch(type){
+	case Tsoa:
+		rp->soa = emalloc(sizeof(*rp->soa));
+		rp->soa->slaves = nil;
+		break;
+	case Tkey:
+		rp->key = emalloc(sizeof(*rp->key));
+		break;
+	case Tcert:
+		rp->cert = emalloc(sizeof(*rp->cert));
+		break;
+	case Tsig:
+		rp->sig = emalloc(sizeof(*rp->sig));
+		break;
+	case Tnull:
+		rp->null = emalloc(sizeof(*rp->null));
+		break;
+	}
+	rp->ttl = 0;
+	rp->expire = 0;
+	rp->next = 0;
+	return rp;
+}
+
+/*
+ *  free a resource record and any related structs
+ */
+void
+rrfree(RR *rp)
+{
+	DN *dp;
+	RR *nrp;
+	Txt *t;
+
+	assert(rp->magic = RRmagic);
+	assert(!rp->cached);
+
+	dp = rp->owner;
+	if(dp){
+		assert(dp->magic == DNmagic);
+		for(nrp = dp->rr; nrp; nrp = nrp->next)
+			assert(nrp != rp); /* "rrfree of live rr" */;
+	}
+
+	switch(rp->type){
+	case Tsoa:
+		freeserverlist(rp->soa->slaves);
+		free(rp->soa);
+		break;
+	case Tkey:
+		free(rp->key->data);
+		free(rp->key);
+		break;
+	case Tcert:
+		free(rp->cert->data);
+		free(rp->cert);
+		break;
+	case Tsig:
+		free(rp->sig->data);
+		free(rp->sig);
+		break;
+	case Tnull:
+		free(rp->null->data);
+		free(rp->null);
+		break;
+	case Ttxt:
+		while(rp->txt != nil){
+			t = rp->txt;
+			rp->txt = t->next;
+			free(t->p);
+			free(t);
+		}
+		break;
+	}
+
+	rp->magic = ~rp->magic;
+	free(rp);
+}
+
+typedef struct Scan	Scan;
+struct Scan
+{
+	uchar	*base;
+	uchar	*p;
+	uchar	*ep;
+	char	*err;
+};
+
+#define NAME(x)		gname(x, sp)
+#define SYMBOL(x)	(x = gsym(sp))
+#define STRING(x)	(x = gstr(sp))
+#define USHORT(x)	(x = gshort(sp))
+#define ULONG(x)	(x = glong(sp))
+#define UCHAR(x)	(x = gchar(sp))
+#define V4ADDR(x)	(x = gv4addr(sp))
+#define V6ADDR(x)	(x = gv6addr(sp))
+#define BYTES(x, y)	(y = gbytes(sp, &x, len - (sp->p - data)))
+
+static char *toolong = "too long";
+
+/*
+ *  get a ushort/ulong
+ */
+static ushort
+gchar(Scan *sp)
+{
+	ushort x;
+
+	if(sp->err)
+		return 0;
+	if(sp->ep - sp->p < 1){
+		sp->err = toolong;
+		return 0;
+	}
+	x = sp->p[0];
+	sp->p += 1;
+	return x;
+}
+static ushort
+gshort(Scan *sp)
+{
+	ushort x;
+
+	if(sp->err)
+		return 0;
+	if(sp->ep - sp->p < 2){
+		sp->err = toolong;
+		return 0;
+	}
+	x = (sp->p[0]<<8) | sp->p[1];
+	sp->p += 2;
+	return x;
+}
+static ulong
+glong(Scan *sp)
+{
+	ulong x;
+
+	if(sp->err)
+		return 0;
+	if(sp->ep - sp->p < 4){
+		sp->err = toolong;
+		return 0;
+	}
+	x = (sp->p[0]<<24) | (sp->p[1]<<16) | (sp->p[2]<<8) | sp->p[3];
+	sp->p += 4;
+	return x;
+}
+
+/*
+ *  get an ip address
+ */
+static DN*
+gv4addr(Scan *sp)
+{
+	char addr[32];
+
+	if(sp->err)
+		return 0;
+	if(sp->ep - sp->p < 4){
+		sp->err = toolong;
+		return 0;
+	}
+	snprint(addr, sizeof(addr), "%V", sp->p);
+	sp->p += 4;
+
+	return dnlookup(addr, Cin, 1);
+}
+static DN*
+gv6addr(Scan *sp)
+{
+	char addr[64];
+
+	if(sp->err)
+		return 0;
+	if(sp->ep - sp->p < IPaddrlen){
+		sp->err = toolong;
+		return 0;
+	}
+	snprint(addr, sizeof(addr), "%I", sp->p);
+	sp->p += IPaddrlen;
+
+	return dnlookup(addr, Cin, 1);
+}
+
+/*
+ *  get a string.  make it an internal symbol.
+ */
+static DN*
+gsym(Scan *sp)
+{
+	int n;
+	char sym[Strlen+1];
+
+	if(sp->err)
+		return 0;
+	n = *(sp->p++);
+	if(sp->p+n > sp->ep){
+		sp->err = toolong;
+		return 0;
+	}
+
+	if(n > Strlen){
+		sp->err = "illegal string";
+		return 0;
+	}
+	strncpy(sym, (char*)sp->p, n);
+	sym[n] = 0;
+	sp->p += n;
+
+	return dnlookup(sym, Csym, 1);
+}
+
+/*
+ *  get a string.  don't make it an internal symbol.
+ */
+static Txt*
+gstr(Scan *sp)
+{
+	int n;
+	char sym[Strlen+1];
+	Txt *t;
+
+	if(sp->err)
+		return 0;
+	n = *(sp->p++);
+	if(sp->p+n > sp->ep){
+		sp->err = toolong;
+		return 0;
+	}
+
+	if(n > Strlen){
+		sp->err = "illegal string";
+		return 0;
+	}
+	strncpy(sym, (char*)sp->p, n);
+	sym[n] = 0;
+	sp->p += n;
+
+	t = emalloc(sizeof(*t));
+	t->next = nil;
+	t->p = estrdup(sym);
+	return t;
+}
+
+/*
+ *  get a sequence of bytes
+ */
+static int
+gbytes(Scan *sp, uchar **p, int n)
+{
+	if(sp->err)
+		return 0;
+	if(sp->p+n > sp->ep || n < 0){
+		sp->err = toolong;
+		return 0;
+	}
+	*p = emalloc(n);
+	memmove(*p, sp->p, n);
+	sp->p += n;
+
+	return n;
+}
+
+/*
+ *  get a domain name.  'to' must point to a buffer at least Domlen+1 long.
+ */
+static char*
+gname(char *to, Scan *sp)
+{
+	int len, off;
+	int pointer;
+	int n;
+	char *tostart;
+	char *toend;
+	uchar *p;
+
+	tostart = to;
+	if(sp->err)
+		goto err;
+	pointer = 0;
+	p = sp->p;
+	toend = to + Domlen;
+	for(len = 0; *p; len += pointer ? 0 : (n+1)){
+		if((*p & 0xc0) == 0xc0){
+			/* pointer to other spot in message */
+			if(pointer++ > 10){
+				sp->err = "pointer loop";
+				goto err;
+			}
+			off = ((p[0]<<8) + p[1]) & 0x3ff;
+			p = sp->base + off;
+			if(p >= sp->ep){
+				sp->err = "bad pointer";
+				goto err;
+			}
+			n = 0;
+			continue;
+		}
+		n = *p++;
+		if(len + n < Domlen - 1){
+			if(to + n > toend){
+				sp->err = toolong;
+				goto err;
+			}
+			memmove(to, p, n);
+			to += n;
+		}
+		p += n;
+		if(*p){
+			if(to >= toend){
+				sp->err = toolong;
+				goto err;
+			}
+			*to++ = '.';
+		}
+	}
+	*to = 0;
+	if(pointer)
+		sp->p += len + 2;	/* + 2 for pointer */
+	else
+		sp->p += len + 1;	/* + 1 for the null domain */
+	return tostart;
+err:
+	*tostart = 0;
+	return tostart;
+}
+
+/*
+ *  convert the next RR from a message
+ */
+static RR*
+convM2RR(Scan *sp)
+{
+	RR *rp;
+	int type;
+	int class;
+	uchar *data;
+	int len;
+	char dname[Domlen+1];
+	Txt *t, **l;
+
+retry:
+	NAME(dname);
+	USHORT(type);
+	USHORT(class);
+
+	rp = rralloc(type);
+	rp->owner = dnlookup(dname, class, 1);
+	rp->type = type;
+
+	ULONG(rp->ttl);
+	rp->ttl += now;
+	USHORT(len);
+	data = sp->p;
+
+	if(sp->p + len > sp->ep)
+		sp->err = toolong;
+	if(sp->err){
+		rrfree(rp);
+		return 0;
+	}
+
+	switch(type){
+	default:
+		/* unknown type, just ignore it */
+		sp->p = data + len;
+		rrfree(rp);
+		goto retry;
+	case Thinfo:
+		SYMBOL(rp->cpu);
+		SYMBOL(rp->os);
+		break;
+	case Tcname:
+	case Tmb:
+	case Tmd:
+	case Tmf:
+	case Tns:
+		rp->host = dnlookup(NAME(dname), Cin, 1);
+		break;
+	case Tmg:
+	case Tmr:
+		rp->mb = dnlookup(NAME(dname), Cin, 1);
+		break;
+	case Tminfo:
+		rp->rmb = dnlookup(NAME(dname), Cin, 1);
+		rp->mb = dnlookup(NAME(dname), Cin, 1);
+		break;
+	case Tmx:
+		USHORT(rp->pref);
+		rp->host = dnlookup(NAME(dname), Cin, 1);
+		break;
+	case Ta:
+		V4ADDR(rp->ip);
+		break;
+	case Taaaa:
+		V6ADDR(rp->ip);
+		break;
+	case Tptr:
+		rp->ptr = dnlookup(NAME(dname), Cin, 1);
+		break;
+	case Tsoa:
+		rp->host = dnlookup(NAME(dname), Cin, 1);
+		rp->rmb = dnlookup(NAME(dname), Cin, 1);
+		ULONG(rp->soa->serial);
+		ULONG(rp->soa->refresh);
+		ULONG(rp->soa->retry);
+		ULONG(rp->soa->expire);
+		ULONG(rp->soa->minttl);
+		break;
+	case Ttxt:
+		l = &rp->txt;
+		*l = nil;
+		while(sp->p-data < len){
+			STRING(t);
+			*l = t;
+			l = &t->next;
+		}
+		break;
+	case Tnull:
+		BYTES(rp->null->data, rp->null->dlen);
+		break;
+	case Trp:
+		rp->rmb = dnlookup(NAME(dname), Cin, 1);
+		rp->rp = dnlookup(NAME(dname), Cin, 1);
+		break;
+	case Tkey:
+		USHORT(rp->key->flags);
+		UCHAR(rp->key->proto);
+		UCHAR(rp->key->alg);
+		BYTES(rp->key->data, rp->key->dlen);
+		break;
+	case Tsig:
+		USHORT(rp->sig->type);
+		UCHAR(rp->sig->alg);
+		UCHAR(rp->sig->labels);
+		ULONG(rp->sig->ttl);
+		ULONG(rp->sig->exp);
+		ULONG(rp->sig->incep);
+		USHORT(rp->sig->tag);
+		rp->sig->signer = dnlookup(NAME(dname), Cin, 1);
+		BYTES(rp->sig->data, rp->sig->dlen);
+		break;
+	case Tcert:
+		USHORT(rp->cert->type);
+		USHORT(rp->cert->tag);
+		UCHAR(rp->cert->alg);
+		BYTES(rp->cert->data, rp->cert->dlen);
+		break;
+	}
+	if(sp->p - data != len)
+		sp->err = "bad RR len";
+	return rp;
+}
+
+/*
+ *  convert the next question from a message
+ */
+static RR*
+convM2Q(Scan *sp)
+{
+	char dname[Domlen+1];
+	int type;
+	int class;
+	RR *rp;
+
+	NAME(dname);
+	USHORT(type);
+	USHORT(class);
+	if(sp->err)
+		return 0;
+
+	rp = rralloc(type);
+	rp->owner = dnlookup(dname, class, 1);
+
+	return rp;
+}
+
+static RR*
+rrloop(Scan *sp, int count, int quest)
+{
+	int i;
+	static char errbuf[64];
+	RR *first, *rp, **l;
+
+	if(sp->err)
+		return 0;
+	l = &first;
+	first = 0;
+	for(i = 0; i < count; i++){
+		rp = quest ? convM2Q(sp) : convM2RR(sp);
+		if(rp == 0)
+			break;
+		if(sp->err){
+			rrfree(rp);
+			break;
+		}
+		*l = rp;
+		l = &rp->next;
+	}
+	return first;
+}
+
+/*
+ *  convert the next DNS from a message stream
+ */
+char*
+convM2DNS(uchar *buf, int len, DNSmsg *m)
+{
+	Scan scan;
+	Scan *sp;
+	char *err;
+
+	scan.base = buf;
+	scan.p = buf;
+	scan.ep = buf + len;
+	scan.err = 0;
+	sp = &scan;
+	memset(m, 0, sizeof(DNSmsg));
+	USHORT(m->id);
+	USHORT(m->flags);
+	USHORT(m->qdcount);
+	USHORT(m->ancount);
+	USHORT(m->nscount);
+	USHORT(m->arcount);
+	m->qd = rrloop(sp, m->qdcount, 1);
+	m->an = rrloop(sp, m->ancount, 0);
+	m->ns = rrloop(sp, m->nscount, 0);
+	err = scan.err;				/* live with bad ar's */
+	m->ar = rrloop(sp, m->arcount, 0);
+	return err;
+}

+ 2 - 1
sys/src/cmd/ip/snoopy/mkfile

@@ -5,6 +5,7 @@ PROTOS=\
 	arp\
 	bootp\
 	dhcp\
+	dns\
 	dump\
 	eap\
 	eap_identity\
@@ -46,6 +47,7 @@ HFILES=dat.h\
 	protos.h\
 	y.tab.h\
 
+YFILES=filter.y
 
 BIN=/$objtype/bin
 UPDATE=\
@@ -79,4 +81,3 @@ protos.c: mkfile
 		echo '};'
 	} > protos.c
 
-y.tab.c: filter.y

+ 1 - 0
sys/src/cmd/ip/snoopy/tcp.c

@@ -50,6 +50,7 @@ static Field p_fields[] =
 
 static Mux p_mux[] =
 {
+	{"dns",	53, },
 	{"ninep",	17007, },	/* exportfs */
 	{"ninep",	564, },		/* 9fs */
 	{"ninep",	17005, },	/* ocpu */

+ 1 - 0
sys/src/cmd/ip/snoopy/udp.c

@@ -39,6 +39,7 @@ static Field p_fields[] =
 
 static Mux p_mux[] =
 {
+	{"dns",	53, },
 	{"bootp",	67, },
 	{"ninep",	6346, },	/* tvs */
 	{"rtp",		ANYPORT, },

+ 26 - 8
sys/src/cmd/ndb/dn.c

@@ -448,13 +448,17 @@ dnauthdb(void)
  *  garbage collect.  block while garbage collecting.
  */
 int
-getactivity(Request *req)
+getactivity(Request *req, int recursive)
 {
 	int rv;
 
-	if(traceactivity) syslog(0, "dns", "get %d by %d", dnvars.active, getpid());
+	if(traceactivity) syslog(0, "dns", "get %d by %d from %p", dnvars.active, getpid(), getcallerpc(&req));
 	lock(&dnvars);
-	while(dnvars.mutex){
+	/*
+	 * can't block here if we're already holding one
+	 * of the dnvars.active (recursive).  will deadlock.
+	 */
+	while(!recursive && dnvars.mutex){
 		unlock(&dnvars);
 		sleep(200);
 		lock(&dnvars);
@@ -467,7 +471,7 @@ getactivity(Request *req)
 	return rv;
 }
 void
-putactivity(void)
+putactivity(int recursive)
 {
 	static ulong lastclean;
 
@@ -478,8 +482,10 @@ putactivity(void)
 
 	/*
 	 *  clean out old entries and check for new db periodicly
+	 *  can't block here if being called to let go a "recursive" lock
+	 *  or we'll deadlock waiting for ourselves to give up the dnvars.active.
 	 */
-	if(dnvars.mutex || (needrefresh == 0 && dnvars.active > 0)){
+	if(recursive || dnvars.mutex || (needrefresh == 0 && dnvars.active > 0)){
 		unlock(&dnvars);
 		return;
 	}
@@ -1234,21 +1240,33 @@ void
 slave(Request *req)
 {
 	static int slaveid;
+	int ppid;
 
 	if(req->isslave)
 		return;		/* we're already a slave process */
 
+	/*
+	 * These calls to putactivity cannot block. 
+	 * After getactivity(), the current process is counted
+	 * twice in dnvars.active (one will pass to the child).
+	 * If putactivity tries to wait for dnvars.active == 0,
+	 * it will never happen.
+	 */
+
 	/* limit parallelism */
-	if(getactivity(req) > Maxactive){
-		putactivity();
+	if(getactivity(req, 1) > Maxactive){
+		if(traceactivity) syslog(0, "dns", "[%d] too much activity", getpid());
+		putactivity(1);
 		return;
 	}
 
+	ppid = getpid();
 	switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
 	case -1:
-		putactivity();
+		putactivity(1);
 		break;
 	case 0:
+		if(traceactivity) syslog(0, "dns", "[%d] take activity from %d", ppid, getpid());
 		req->isslave = 1;
 		break;
 	default:

+ 2 - 2
sys/src/cmd/ndb/dnnotify.c

@@ -150,9 +150,9 @@ notifyproc(void)
 	req.isslave = 1;	/* son't fork off subprocesses */
 
 	for(;;){
-		getactivity(&req);
+		getactivity(&req, 0);
 		notify_areas(owned, &req);
-		putactivity();
+		putactivity(0);
 		sleep(60*1000);
 	}
 }

+ 1 - 1
sys/src/cmd/ndb/dnresolve.c

@@ -94,7 +94,7 @@ dnresolve1(char *name, int class, int type, Request *req, int depth, int recurse
 	char *cp;
 
 	if(debug)
-		syslog(0, LOG, "dnresolve1 %s %d %d", name, type, class);
+		syslog(0, LOG, "[%d] dnresolve1 %s %d %d", getpid(), name, type, class);
 
 	/* only class Cin implemented so far */
 	if(class != Cin)

+ 6 - 6
sys/src/cmd/ndb/dns.c

@@ -376,7 +376,7 @@ io(void)
 	 *  through 'mret'.
 	 */
 	if(setjmp(req.mret))
-		putactivity();
+		putactivity(0);
 	req.isslave = 0;
 	for(;;){
 		n = read9pmsg(mfd[0], mdata, sizeof mdata);
@@ -393,7 +393,7 @@ io(void)
 		if(debug)
 			syslog(0, logfile, "%F", &job->request);
 
-		getactivity(&req);
+		getactivity(&req, 0);
 		req.aborttime = now + 60;	/* don't spend more than 60 seconds */
 
 		switch(job->request.type){
@@ -447,11 +447,11 @@ io(void)
 		 *  slave processes die after replying
 		 */
 		if(req.isslave){
-			putactivity();
+			putactivity(0);
 			_exits(0);
 		}
 	
-		putactivity();
+		putactivity(0);
 	}
 }
 
@@ -871,8 +871,8 @@ logsend(int id, int subid, uchar *addr, char *sname, char *rname, int type)
 {
 	char buf[12];
 
-	syslog(0, LOG, "%d.%d: sending to %I/%s %s %s",
-		id, subid, addr, sname, rname, rrname(type, buf, sizeof buf));
+	syslog(0, LOG, "[%d] %d.%d: sending to %I/%s %s %s",
+		getpid(), id, subid, addr, sname, rname, rrname(type, buf, sizeof buf));
 }
 
 RR*

+ 2 - 2
sys/src/cmd/ndb/dns.h

@@ -370,8 +370,8 @@ extern int	rrtype(char*);
 extern char*	rrname(int, char*, int);
 extern int	tsame(int, int);
 extern void	dndump(char*);
-extern int	getactivity(Request*);
-extern void	putactivity(void);
+extern int	getactivity(Request*, int);
+extern void	putactivity(int);
 extern void	abort(); /* char*, ... */;
 extern void	warning(char*, ...);
 extern void	slave(Request*);

+ 2 - 2
sys/src/cmd/ndb/dnsdebug.c

@@ -414,7 +414,7 @@ doquery(char *name, char *tstr)
 		return;
 	}
 
-	getactivity(&req);
+	getactivity(&req, 0);
 	req.isslave = 1;
 	req.aborttime = now + 60;	/* don't spend more than 60 seconds */
 	rr = dnresolve(buf, Cin, type, &req, 0, 0, Recurse, rooted, 0);
@@ -426,7 +426,7 @@ doquery(char *name, char *tstr)
 	}
 	rrfreelist(rr);
 
-	putactivity();
+	putactivity(0);
 }
 
 void

+ 24 - 8
sys/src/cmd/ndb/dnstcp.c

@@ -30,6 +30,13 @@ static void	dnzone(DNSmsg*, DNSmsg*, Request*);
 static void	getcaller(char*);
 static void	refreshmain(char*);
 
+void
+usage(void)
+{
+	fprint(2, "usage: %s [-rR] [-f ndb-file] [-x netmtpt]\n", argv0);
+	exits("usage");
+}
+
 void
 main(int argc, char *argv[])
 {
@@ -42,17 +49,23 @@ main(int argc, char *argv[])
 	char *ext = "";
 
 	ARGBEGIN{
+	case 'R':
+		norecursion = 1;
+		break;
 	case 'd':
 		debug++;
 		break;
 	case 'f':
-		dbfile = ARGF();
+		dbfile = EARGF(usage());
 		break;
 	case 'r':
 		resolver = 1;
 		break;
 	case 'x':
-		ext = ARGF();
+		ext = EARGF(usage());
+		break;
+	default:
+		usage();
 		break;
 	}ARGEND
 
@@ -75,7 +88,7 @@ main(int argc, char *argv[])
 	req.isslave = 0;
 
 	/* loop on requests */
-	for(;; putactivity()){
+	for(;; putactivity(0)){
 		now = time(0);
 		memset(&repmsg, 0, sizeof(repmsg));
 		alarm(10*60*1000);
@@ -83,7 +96,7 @@ main(int argc, char *argv[])
 		alarm(0);
 		if(len <= 0)
 			break;
-		getactivity(&req);
+		getactivity(&req, 0);
 		req.aborttime = now + 15*Min;
 		err = convM2DNS(buf, len, &reqmsg);
 		if(err){
@@ -104,7 +117,8 @@ main(int argc, char *argv[])
 		}
 
 		if(debug)
-			syslog(0, logfile, "%d: serve (%s) %d %s %s",
+			syslog(0, logfile, "[%d] %d: serve (%s) %d %s %s",
+				getpid(),
 				req.id, caller,
 				reqmsg.id,
 				reqmsg.qd->owner->name,
@@ -130,7 +144,7 @@ main(int argc, char *argv[])
 		rrfreelist(reqmsg.ar);
 
 		if(req.isslave){
-			putactivity();
+			putactivity(0);
 			_exits(0);
 		}
 	}
@@ -183,7 +197,7 @@ reply(int fd, DNSmsg *rep, Request *req)
 	buf[1] = len;
 	rv = write(fd, buf, len+2);
 	if(rv != len+2){
-		syslog(0, logfile, "sending reply: %d instead of %d", rv, len+2);
+		syslog(0, logfile, "[%d] sending reply: %d instead of %d", getpid(), rv, len+2);
 		exits(0);
 	}
 }
@@ -234,10 +248,12 @@ dnzone(DNSmsg *reqp, DNSmsg *repp, Request *req)
 
 	memset(repp, 0, sizeof(*repp));
 	repp->id = reqp->id;
-	repp->flags = Fauth | Fresp | Fcanrec | Oquery;
 	repp->qd = reqp->qd;
 	reqp->qd = reqp->qd->next;
 	repp->qd->next = 0;
+	repp->flags = Fauth | Fresp | Oquery;
+	if(!norecursion)
+		repp->flags |= Fcanrec;
 	dp = repp->qd->owner;
 
 	/* send the soa */

+ 9 - 6
sys/src/cmd/ndb/dnudpserver.c

@@ -97,11 +97,11 @@ restart:
 	while((fd = udpannounce(mntpt)) < 0)
 		sleep(5000);
 	if(setjmp(req.mret))
-		putactivity();
+		putactivity(0);
 	req.isslave = 0;
 
 	/* loop on requests */
-	for(;; putactivity()){
+	for(;; putactivity(0)){
 		memset(&repmsg, 0, sizeof(repmsg));
 		memset(&reqmsg, 0, sizeof(reqmsg));
 		alarm(60*1000);
@@ -111,7 +111,7 @@ restart:
 			goto restart;
 		uh = (OUdphdr*)buf;
 		len -= OUdphdrsize;
-		getactivity(&req);
+		getactivity(&req, 0);
 		req.aborttime = now + 30;	/* don't spend more than 30 seconds */
 		err = convM2DNS(&buf[OUdphdrsize], len, &reqmsg);
 		if(err){
@@ -174,7 +174,7 @@ freereq:
 		rrfreelist(reqmsg.ar);
 
 		if(req.isslave){
-			putactivity();
+			putactivity(0);
 			_exits(0);
 		}
 
@@ -190,6 +190,7 @@ static char *ohmsg = "oldheaders";
 static int
 udpannounce(char *mntpt)
 {
+	static int whined;
 	int data, ctl;
 	char dir[64];
 	char datafile[64+6];
@@ -198,7 +199,8 @@ udpannounce(char *mntpt)
 	sprint(datafile, "%s/udp!*!dns", mntpt);
 	ctl = announce(datafile, dir);
 	if(ctl < 0){
-		warning("can't announce on dns udp port");
+		if(!whined++)
+			warning("can't announce on dns udp port");
 		return -1;
 	}
 	snprint(datafile, sizeof(datafile), "%s/data", dir);
@@ -210,7 +212,8 @@ udpannounce(char *mntpt)
 	data = open(datafile, ORDWR);
 	if(data < 0){
 		close(ctl);
-		warning("can't announce on dns udp port");
+		if(!whined++)
+			warning("can't announce on dns udp port");
 		return -1;
 	}
 

+ 4 - 2
sys/src/cmd/usb/lib/device.c

@@ -37,8 +37,9 @@ opendev(int ctlrno, int id)
 		sprint(name, "/dev/usb%d/new", ctlrno);
 		if((d->ctl = open(name, ORDWR)) < 0){
 		Error0:
-			close(d->ctl);
 			werrstr("open %s: %r", name);
+			if(d->ctl >= 0)
+				close(d->ctl);
 			free(d);
 			/* return nil; */
 			sysfatal("%r");
@@ -58,7 +59,8 @@ opendev(int ctlrno, int id)
 	strcpy(p, "setup");
 	if((d->setup = open(name, ORDWR)) < 0){
 	Error1:
-		close(d->setup);
+		if(d->setup >= 0)
+			close(d->setup);
 		goto Error0;
 	}
 

Some files were not shown because too many files changed in this diff