Browse Source

Plan 9 from Bell Labs 2007-10-26

David du Colombier 16 years ago
parent
commit
5a6fcc0581

+ 25 - 21
dist/replica/_plan9.db

@@ -1,17 +1,17 @@
 386 - 20000000775 sys sys 1010957353 0
-386/9load - 775 sys sys 1191886962 330276
-386/9loaddebug - 775 sys sys 1193198599 439897
-386/9loadlite - 775 sys sys 1191886972 153588
-386/9loadlitedebug - 775 sys sys 1193198603 225425
-386/9pc - 775 sys sys 1189053434 2038499
-386/9pc.gz - 664 sys sys 1189053435 865376
-386/9pccpu - 775 sys sys 1189053453 1705749
-386/9pccpu.gz - 664 sys sys 1189053454 736710
-386/9pcdisk - 775 sys sys 1189229899 2230547
-386/9pcdisk.gz - 664 sys sys 1189229899 948797
-386/9pcf - 775 sys sys 1189310638 2705317
-386/9pcf.gz - 664 sys sys 1189310663 1164515
-386/9pxeload - 775 sys sys 1191886982 330276
+386/9load - 775 sys sys 1193358654 336916
+386/9loaddebug - 775 sys sys 1193358658 450489
+386/9loadlite - 775 sys sys 1193358657 160216
+386/9loadlitedebug - 775 sys sys 1193358659 236032
+386/9pc - 775 sys sys 1192646200 2054406
+386/9pc.gz - 664 sys sys 1192646200 873537
+386/9pccpu - 775 sys sys 1191889923 1749481
+386/9pccpu.gz - 664 sys sys 1191889923 755214
+386/9pcdisk - 775 sys sys 1192741561 2286983
+386/9pcdisk.gz - 664 sys sys 1192741561 973813
+386/9pcf - 775 sys sys 1191889940 2874011
+386/9pcf.gz - 664 sys sys 1191889940 1230163
+386/9pxeload - 775 sys sys 1193358656 336920
 386/bin - 20000000775 sys sys 1018897690 0
 386/bin/8a - 775 sys sys 1168402260 116604
 386/bin/8c - 775 sys sys 1190520740 367214
@@ -215,6 +215,7 @@
 386/bin/disk/mkext - 775 sys sys 1168402303 82886
 386/bin/disk/mkfs - 775 sys sys 1168402303 87969
 386/bin/disk/mksacfs - 775 sys sys 1020319074 71451
+386/bin/disk/partfs - 775 sys sys 1193282249 149872
 386/bin/disk/prep - 775 sys sys 1168402303 96167
 386/bin/disk/sacfs - 775 sys sys 1020319075 79882
 386/bin/dossrv - 775 sys sys 1178568267 136537
@@ -5813,6 +5814,7 @@ sys/doc/title - 664 sys sys 1018974170 740
 sys/doc/title.ps - 664 sys sys 1018974170 214289
 sys/doc/trademarks.ps - 664 sys sys 960837912 217896
 sys/doc/troff.ms - 664 sys sys 953237047 120683
+sys/doc/troff.pdf - 664 sys sys 1193286693 246065
 sys/doc/troff.ps - 664 sys sys 1091459051 782310
 sys/doc/utf.ms - 664 sys sys 1138396447 41735
 sys/doc/utf.ps - 664 sys sys 960837922 363085
@@ -7805,7 +7807,7 @@ sys/man/7/scat - 664 sys sys 970069855 8904
 sys/man/8 - 20000000775 sys sys 1162240005 0
 sys/man/8/0intro - 664 sys sys 944959679 247
 sys/man/8/6in4 - 664 sys sys 1186182195 2330
-sys/man/8/9load - 664 sys sys 1193175486 9717
+sys/man/8/9load - 664 sys sys 1193364197 9814
 sys/man/8/9pcon - 664 sys sys 1145881850 2234
 sys/man/8/INDEX - 664 sys sys 1183260468 2773
 sys/man/8/INDEX.html - 664 sys sys 1183240488 8619
@@ -7849,7 +7851,7 @@ sys/man/8/ping - 664 sys sys 1169105315 3650
 sys/man/8/plan9.ini - 664 sys sys 1190241912 23835
 sys/man/8/pop3 - 664 sys sys 1063854676 2720
 sys/man/8/ppp - 664 sys sys 1187046045 4430
-sys/man/8/prep - 664 sys sys 1193181551 14162
+sys/man/8/prep - 664 sys sys 1193284681 14201
 sys/man/8/qer - 664 sys sys 1067723129 4909
 sys/man/8/reboot - 664 sys sys 1162423006 443
 sys/man/8/replica - 664 sys sys 1138479158 6383
@@ -9133,6 +9135,7 @@ sys/src/boot/pc - 20000000775 sys sys 1144961189 0
 sys/src/boot/pc/8250.c - 664 sys sys 1015007947 5727
 sys/src/boot/pc/ahci.h - 664 sys sys 1186366104 6318
 sys/src/boot/pc/alarm.c - 664 sys sys 1015007947 1668
+sys/src/boot/pc/aoe.h - 664 sys sys 1193336543 826
 sys/src/boot/pc/apm.c - 664 sys sys 1015007947 289
 sys/src/boot/pc/bcom.c - 664 sys sys 1032215919 6421
 sys/src/boot/pc/boot.c - 664 sys sys 1130887226 8421
@@ -9144,7 +9147,7 @@ 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 1190921443 3637
-sys/src/boot/pc/devbios.c - 664 sys sys 1193171393 9376
+sys/src/boot/pc/devbios.c - 664 sys sys 1193353518 9297
 sys/src/boot/pc/devbios.h - 664 sys sys 1193167027 493
 sys/src/boot/pc/devfloppy.c - 664 sys sys 1032215913 15505
 sys/src/boot/pc/devfloppy.h - 664 sys sys 1032409559 4081
@@ -9165,7 +9168,7 @@ 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 1156429147 21582
 sys/src/boot/pc/ether82557.c - 664 sys sys 1140802406 19090
-sys/src/boot/pc/ether82563.c - 664 sys sys 1181517000 25452
+sys/src/boot/pc/ether82563.c - 664 sys sys 1193335413 25390
 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
@@ -9192,12 +9195,12 @@ sys/src/boot/pc/kfs.h - 664 sys sys 1032215924 861
 sys/src/boot/pc/kfsboot.c - 664 sys sys 1032215914 4788
 sys/src/boot/pc/l.s - 664 sys sys 1193167045 18213
 sys/src/boot/pc/lib.h - 664 sys sys 1190921452 2847
-sys/src/boot/pc/load.c - 664 sys sys 1193171385 9602
+sys/src/boot/pc/load.c - 664 sys sys 1193359334 9765
 sys/src/boot/pc/mbr.s - 664 sys sys 1015007953 6234
 sys/src/boot/pc/mem.h - 664 sys sys 1190921475 3437
 sys/src/boot/pc/memory.c - 664 sys sys 1019533021 10272
-sys/src/boot/pc/mkfile - 664 sys sys 1193171361 3193
-sys/src/boot/pc/noether.c - 664 sys sys 1094674488 358
+sys/src/boot/pc/mkfile - 664 sys sys 1193359312 3224
+sys/src/boot/pc/noether.c - 664 sys sys 1193336537 416
 sys/src/boot/pc/part.c - 664 sys sys 1114697151 7153
 sys/src/boot/pc/pbs.s - 664 sys sys 1143465387 8291
 sys/src/boot/pc/pbsdisk - 775 sys sys 1017854325 509
@@ -9211,7 +9214,9 @@ sys/src/boot/pc/queue.c - 664 sys sys 1015007954 566
 sys/src/boot/pc/sd.h - 664 sys sys 1153333456 2244
 sys/src/boot/pc/sd53c8xx.c - 664 sys sys 1186031515 52082
 sys/src/boot/pc/sd53c8xx.i - 664 sys sys 1015007955 27245
+sys/src/boot/pc/sdaoe.c - 664 sys sys 1193341405 11270
 sys/src/boot/pc/sdata.c - 664 sys sys 1175564193 38846
+sys/src/boot/pc/sdbios.c - 664 sys sys 1193359341 3001
 sys/src/boot/pc/sdiahci.c - 664 sys sys 1191886818 27133
 sys/src/boot/pc/sdmylex.c - 664 sys sys 1171783051 28694
 sys/src/boot/pc/sdscsi.c - 664 sys sys 1144961224 7006
@@ -15743,4 +15748,3 @@ usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
-386/bin/disk/partfs - 775 sys sys 1193282249 149872

+ 24 - 20
dist/replica/plan9.db

@@ -1,17 +1,17 @@
 386 - 20000000775 sys sys 1010957353 0
-386/9load - 775 sys sys 1191886962 330276
-386/9loaddebug - 775 sys sys 1193198599 439897
-386/9loadlite - 775 sys sys 1191886972 153588
-386/9loadlitedebug - 775 sys sys 1193198603 225425
-386/9pc - 775 sys sys 1189053434 2038499
-386/9pc.gz - 664 sys sys 1189053435 865376
-386/9pccpu - 775 sys sys 1189053453 1705749
-386/9pccpu.gz - 664 sys sys 1189053454 736710
-386/9pcdisk - 775 sys sys 1189229899 2230547
-386/9pcdisk.gz - 664 sys sys 1189229899 948797
-386/9pcf - 775 sys sys 1189310638 2705317
-386/9pcf.gz - 664 sys sys 1189310663 1164515
-386/9pxeload - 775 sys sys 1191886982 330276
+386/9load - 775 sys sys 1193358654 336916
+386/9loaddebug - 775 sys sys 1193358658 450489
+386/9loadlite - 775 sys sys 1193358657 160216
+386/9loadlitedebug - 775 sys sys 1193358659 236032
+386/9pc - 775 sys sys 1192646200 2054406
+386/9pc.gz - 664 sys sys 1192646200 873537
+386/9pccpu - 775 sys sys 1191889923 1749481
+386/9pccpu.gz - 664 sys sys 1191889923 755214
+386/9pcdisk - 775 sys sys 1192741561 2286983
+386/9pcdisk.gz - 664 sys sys 1192741561 973813
+386/9pcf - 775 sys sys 1191889940 2874011
+386/9pcf.gz - 664 sys sys 1191889940 1230163
+386/9pxeload - 775 sys sys 1193358656 336920
 386/bin - 20000000775 sys sys 1018897690 0
 386/bin/8a - 775 sys sys 1168402260 116604
 386/bin/8c - 775 sys sys 1190520740 367214
@@ -5814,6 +5814,7 @@ sys/doc/title - 664 sys sys 1018974170 740
 sys/doc/title.ps - 664 sys sys 1018974170 214289
 sys/doc/trademarks.ps - 664 sys sys 960837912 217896
 sys/doc/troff.ms - 664 sys sys 953237047 120683
+sys/doc/troff.pdf - 664 sys sys 1193286693 246065
 sys/doc/troff.ps - 664 sys sys 1091459051 782310
 sys/doc/utf.ms - 664 sys sys 1138396447 41735
 sys/doc/utf.ps - 664 sys sys 960837922 363085
@@ -7806,7 +7807,7 @@ sys/man/7/scat - 664 sys sys 970069855 8904
 sys/man/8 - 20000000775 sys sys 1162240005 0
 sys/man/8/0intro - 664 sys sys 944959679 247
 sys/man/8/6in4 - 664 sys sys 1186182195 2330
-sys/man/8/9load - 664 sys sys 1193175486 9717
+sys/man/8/9load - 664 sys sys 1193364197 9814
 sys/man/8/9pcon - 664 sys sys 1145881850 2234
 sys/man/8/INDEX - 664 sys sys 1183260468 2773
 sys/man/8/INDEX.html - 664 sys sys 1183240488 8619
@@ -7850,7 +7851,7 @@ sys/man/8/ping - 664 sys sys 1169105315 3650
 sys/man/8/plan9.ini - 664 sys sys 1190241912 23835
 sys/man/8/pop3 - 664 sys sys 1063854676 2720
 sys/man/8/ppp - 664 sys sys 1187046045 4430
-sys/man/8/prep - 664 sys sys 1193181551 14162
+sys/man/8/prep - 664 sys sys 1193284681 14201
 sys/man/8/qer - 664 sys sys 1067723129 4909
 sys/man/8/reboot - 664 sys sys 1162423006 443
 sys/man/8/replica - 664 sys sys 1138479158 6383
@@ -9134,6 +9135,7 @@ sys/src/boot/pc - 20000000775 sys sys 1144961189 0
 sys/src/boot/pc/8250.c - 664 sys sys 1015007947 5727
 sys/src/boot/pc/ahci.h - 664 sys sys 1186366104 6318
 sys/src/boot/pc/alarm.c - 664 sys sys 1015007947 1668
+sys/src/boot/pc/aoe.h - 664 sys sys 1193336543 826
 sys/src/boot/pc/apm.c - 664 sys sys 1015007947 289
 sys/src/boot/pc/bcom.c - 664 sys sys 1032215919 6421
 sys/src/boot/pc/boot.c - 664 sys sys 1130887226 8421
@@ -9145,7 +9147,7 @@ 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 1190921443 3637
-sys/src/boot/pc/devbios.c - 664 sys sys 1193171393 9376
+sys/src/boot/pc/devbios.c - 664 sys sys 1193353518 9297
 sys/src/boot/pc/devbios.h - 664 sys sys 1193167027 493
 sys/src/boot/pc/devfloppy.c - 664 sys sys 1032215913 15505
 sys/src/boot/pc/devfloppy.h - 664 sys sys 1032409559 4081
@@ -9166,7 +9168,7 @@ 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 1156429147 21582
 sys/src/boot/pc/ether82557.c - 664 sys sys 1140802406 19090
-sys/src/boot/pc/ether82563.c - 664 sys sys 1181517000 25452
+sys/src/boot/pc/ether82563.c - 664 sys sys 1193335413 25390
 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
@@ -9193,12 +9195,12 @@ sys/src/boot/pc/kfs.h - 664 sys sys 1032215924 861
 sys/src/boot/pc/kfsboot.c - 664 sys sys 1032215914 4788
 sys/src/boot/pc/l.s - 664 sys sys 1193167045 18213
 sys/src/boot/pc/lib.h - 664 sys sys 1190921452 2847
-sys/src/boot/pc/load.c - 664 sys sys 1193171385 9602
+sys/src/boot/pc/load.c - 664 sys sys 1193359334 9765
 sys/src/boot/pc/mbr.s - 664 sys sys 1015007953 6234
 sys/src/boot/pc/mem.h - 664 sys sys 1190921475 3437
 sys/src/boot/pc/memory.c - 664 sys sys 1019533021 10272
-sys/src/boot/pc/mkfile - 664 sys sys 1193171361 3193
-sys/src/boot/pc/noether.c - 664 sys sys 1094674488 358
+sys/src/boot/pc/mkfile - 664 sys sys 1193359312 3224
+sys/src/boot/pc/noether.c - 664 sys sys 1193336537 416
 sys/src/boot/pc/part.c - 664 sys sys 1114697151 7153
 sys/src/boot/pc/pbs.s - 664 sys sys 1143465387 8291
 sys/src/boot/pc/pbsdisk - 775 sys sys 1017854325 509
@@ -9212,7 +9214,9 @@ sys/src/boot/pc/queue.c - 664 sys sys 1015007954 566
 sys/src/boot/pc/sd.h - 664 sys sys 1153333456 2244
 sys/src/boot/pc/sd53c8xx.c - 664 sys sys 1186031515 52082
 sys/src/boot/pc/sd53c8xx.i - 664 sys sys 1015007955 27245
+sys/src/boot/pc/sdaoe.c - 664 sys sys 1193341405 11270
 sys/src/boot/pc/sdata.c - 664 sys sys 1175564193 38846
+sys/src/boot/pc/sdbios.c - 664 sys sys 1193359341 3001
 sys/src/boot/pc/sdiahci.c - 664 sys sys 1191886818 27133
 sys/src/boot/pc/sdmylex.c - 664 sys sys 1171783051 28694
 sys/src/boot/pc/sdscsi.c - 664 sys sys 1144961224 7006

+ 27 - 0
dist/replica/plan9.log

@@ -53126,3 +53126,30 @@
 1193272204 0 c sys/src/cmd/disk/partfs.c - 664 sys sys 1193271505 9718
 1193279405 0 c sys/src/cmd/disk/partfs.c - 664 sys sys 1193279294 9714
 1193283004 0 a 386/bin/disk/partfs - 775 sys sys 1193282249 149872
+1193284804 0 c sys/man/8/prep - 664 sys sys 1193284681 14201
+1193288404 0 a sys/doc/troff.pdf - 664 sys sys 1193286693 246065
+1193337003 0 c sys/src/boot/pc/noether.c - 664 sys sys 1193336537 416
+1193337003 1 a sys/src/boot/pc/aoe.h - 664 sys sys 1193336543 826
+1193337003 2 c sys/src/boot/pc/ether82563.c - 664 sys sys 1193335413 25390
+1193340604 0 c sys/src/boot/pc/load.c - 664 sys sys 1193340750 9650
+1193340604 1 c sys/src/boot/pc/mkfile - 664 sys sys 1193340623 3212
+1193340604 2 a sys/src/boot/pc/sdaoe.c - 664 sys sys 1193340560 11236
+1193342404 0 c sys/src/boot/pc/sdaoe.c - 664 sys sys 1193341405 11270
+1193355004 0 c sys/src/boot/pc/devbios.c - 664 sys sys 1193353518 9297
+1193360405 0 c sys/src/boot/pc/load.c - 664 sys sys 1193359334 9765
+1193360405 1 c sys/src/boot/pc/mkfile - 664 sys sys 1193359312 3224
+1193360405 2 a sys/src/boot/pc/sdbios.c - 664 sys sys 1193359341 3001
+1193365804 0 c 386/9load - 775 sys sys 1193358654 336916
+1193365804 1 c 386/9loaddebug - 775 sys sys 1193358658 450489
+1193365804 2 c 386/9loadlite - 775 sys sys 1193358657 160216
+1193365804 3 c 386/9loadlitedebug - 775 sys sys 1193358659 236032
+1193365804 4 c 386/9pc - 775 sys sys 1192646200 2054406
+1193365804 5 c 386/9pc.gz - 664 sys sys 1192646200 873537
+1193365804 6 c 386/9pccpu - 775 sys sys 1191889923 1749481
+1193365804 7 c 386/9pccpu.gz - 664 sys sys 1191889923 755214
+1193365804 8 c 386/9pcdisk - 775 sys sys 1192741561 2286983
+1193365804 9 c 386/9pcdisk.gz - 664 sys sys 1192741561 973813
+1193365804 10 c 386/9pcf - 775 sys sys 1191889940 2874011
+1193365804 11 c 386/9pcf.gz - 664 sys sys 1191889940 1230163
+1193365804 12 c 386/9pxeload - 775 sys sys 1193358656 336920
+1193365804 13 c sys/man/8/9load - 664 sys sys 1193364197 9814

BIN
sys/doc/troff.pdf


+ 12 - 5
sys/man/8/9load

@@ -232,7 +232,8 @@ There is no default partition or pathname.
 (Not in
 .IR 9pxeload .)
 .I 9load
-reads the first LBA device
+loads from a FAT file system on
+the first LBA device
 in the BIOS's list of devices to try to boot from,
 using the BIOS INT 13 calls also used by
 .IR pbslba .
@@ -241,6 +242,16 @@ see the EXAMPLES in
 .IR prep (8)
 for how to format such a device.
 This is mostly useful for booting from USB devices so far.
+.TP
+.B sdB0
+(Not in
+.IR 9pxeload .)
+A special case of
+.BI sd Cn
+that uses
+.B bios0
+to read from a FAT file system.
+Partitions are understood.
 .SS Kernel loading
 When
 .I 9load
@@ -453,7 +464,3 @@ obtains the information normally found in a disc
 file,
 and thereby the kernel to load and boot,
 is not ideal and may change in the future.
-.PP
-The
-.B bios
-device should understand partition tables, if present.

+ 76 - 0
sys/src/boot/pc/aoe.h

@@ -0,0 +1,76 @@
+/*
+ * ATA-over-Ethernet
+ */
+enum {
+	ACata,
+	ACconfig,
+};
+
+enum {
+	AQCread,
+	AQCtest,
+	AQCprefix,
+	AQCset,
+	AQCfset,
+};
+
+enum {
+	AEcmd	= 1,
+	AEarg,
+	AEdev,
+	AEcfg,
+	AEver,
+};
+
+enum {
+	Aoetype	= 0x88a2,
+	Aoever	= 1,
+
+	AFerr	= 1<<2,
+	AFrsp	= 1<<3,
+
+	AAFwrite= 1,
+	AAFext	= 1<<6,
+};
+
+enum {
+	Crd	= 0x20,
+	Crdext	= 0x24,
+	Cwr	= 0x30,
+	Cwrext	= 0x34,
+	Cid	= 0xec,
+};
+
+typedef struct {
+	uchar	dst[Eaddrlen];
+	uchar	src[Eaddrlen];
+	uchar	type[2];
+	uchar	verflag;
+	uchar	error;
+	uchar	major[2];
+	uchar	minor;
+	uchar	cmd;
+	uchar	tag[4];
+} Aoehdr;
+
+typedef struct {
+	Aoehdr;
+	uchar	aflag;
+	uchar	errfeat;
+	uchar	scnt;
+	uchar	cmdstat;
+	uchar	lba[6];
+	uchar	res[2];
+} Aoeata;
+
+typedef struct {
+	Aoehdr;
+	uchar	bufcnt[2];
+	uchar	fwver[2];
+	uchar	scnt;
+	uchar	verccmd;
+	uchar	cslen[2];
+} Aoeqc;
+
+extern char Echange[];
+extern char Enotup[];

+ 0 - 3
sys/src/boot/pc/devbios.c

@@ -1,8 +1,5 @@
 /*
  * boot driver for BIOS devices
- *
- * BUGS:
- *	doesn't understand disk partitions at all; convert to sdbios.c?
  */
 #include <u.h>
 #include "lib.h"

+ 2 - 4
sys/src/boot/pc/ether82563.c

@@ -598,11 +598,9 @@ toringbuf(Ether *ether, Block *bp)
 		rb->len = BLEN(bp);
 		memmove(rb->pkt, bp->rp, rb->len);
 		rb->owner = Host;
-//		print("#l%d: toringbuf: %d %p\n", ether->ctlrno, ether->ri,
-//			ether);
 		ether->ri = NEXT(ether->ri, ether->nrb);
-	}else
-		print("#l%d: toringbuf: dropping packets @ %d\n",
+	} else if (debug)
+		print("#l%d: toringbuf: dropping packets @ ri %d\n",
 			ether->ctlrno, ether->ri);
 }
 

+ 22 - 14
sys/src/boot/pc/load.c

@@ -29,6 +29,7 @@ static char *etherinis[] = {
 	0
 };
 
+/* ordering: devbios must be called before devsd calls sdbios */
 Type types[] = {
 	{	Tfloppy,
 		Fini|Ffs,
@@ -38,14 +39,6 @@ Type types[] = {
 		diskparts,
 		diskinis,
 	},
-	{	Tcd,
-		Fini|Ffs,
-		cdinit, sdinitdev,
-		sdgetfspart, sdaddconf, sdboot,
-		sdprintdevs,
-		diskparts,
-		diskinis,
-	},
 	{	Tether,
 		Fini|Fbootp,
 		etherinit, etherinitdev,
@@ -54,19 +47,27 @@ Type types[] = {
 		etherparts,
 		etherinis,
 	},
-	{	Tsd,
+	{	Tbios,
 		Fini|Ffs,
-		sdinit, sdinitdev,
+		biosinit, biosinitdev,
+		biosgetfspart, nil, biosboot,
+		biosprintdevs,
+		diskparts,
+		diskinis,
+	},
+	{	Tcd,
+		Fini|Ffs,
+		cdinit, sdinitdev,
 		sdgetfspart, sdaddconf, sdboot,
 		sdprintdevs,
 		diskparts,
 		diskinis,
 	},
-	{	Tbios,
+	{	Tsd,
 		Fini|Ffs,
-		biosinit, biosinitdev,
-		biosgetfspart, nil, biosboot,
-		biosprintdevs,
+		sdinit, sdinitdev,
+		sdgetfspart, sdaddconf, sdboot,
+		sdprintdevs,
 		diskparts,
 		diskinis,
 	},
@@ -82,12 +83,16 @@ Type types[] = {
 
 extern SDifc sdataifc;
 extern SDifc sdiahciifc;
+extern SDifc sdaoeifc;
+extern SDifc sdbiosifc;
 
 #ifdef NOSCSI
 
 SDifc* sdifc[] = {
 	&sdataifc,
 	&sdiahciifc,
+	&sdbiosifc,
+	&sdaoeifc,
 	nil,
 };
 
@@ -95,11 +100,14 @@ SDifc* sdifc[] = {
 
 extern SDifc sdmylexifc;
 extern SDifc sd53c8xxifc;
+
 SDifc* sdifc[] = {
 	&sdataifc,
 	&sdiahciifc,
 	&sdmylexifc,
 	&sd53c8xxifc,
+	&sdbiosifc,
+	&sdaoeifc,
 	nil,
 };
 

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

@@ -49,6 +49,8 @@ LOAD=\
 	sd53c8xx.$O\
 	sdiahci.$O\
 	sdscsi.$O\
+	sdaoe.$O\
+	sdbios.$O\
 
 ETHER=\
 	bootp.$O\
@@ -88,6 +90,7 @@ HFILES=\
 	dat.h\
 	fns.h\
 	io.h\
+	aoe.h\
 
 CFLAGS=-FTVw -I.
 

+ 6 - 0
sys/src/boot/pc/noether.c

@@ -27,6 +27,12 @@ etherrxpkt(int, Etherpkt*, int)
 	return -1;
 }
 
+int
+ethertxpkt(int, Etherpkt*, int, int)
+{
+	return -1;
+}
+
 int
 bootpboot(int, char*, Boot*)
 {

+ 734 - 0
sys/src/boot/pc/sdaoe.c

@@ -0,0 +1,734 @@
+/*
+ * aoe sd bootstrap driver, copyright © 2007 coraid
+ */
+
+#include "u.h"
+#include "mem.h"
+#include "lib.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "sd.h"
+#include "aoe.h"
+
+#define uprint(...)	snprint(up->genbuf, sizeof up->genbuf, __VA_ARGS__);
+
+enum {
+	Nctlr	= 4,
+};
+
+enum {
+	/* sync with ahci.h */
+	Dllba 	= 1<<0,
+	Dsmart	= 1<<1,
+	Dpower	= 1<<2,
+	Dnop	= 1<<3,
+	Datapi	= 1<<4,
+	Datapi16= 1<<5,
+};
+
+enum {
+	Tfree	= -1,
+	Tmgmt,
+};
+
+typedef struct Ctlr Ctlr;
+struct Ctlr{
+	Ctlr	*next;
+	SDunit	*unit;
+
+	int	ctlrno;
+	int	major;
+	int	minor;
+	uchar	ea[Eaddrlen];
+	ushort	lasttag;
+
+	ulong	vers;
+	uchar	mediachange;
+	uchar	flag;
+	uchar	smart;
+	uchar	smartrs;
+	uchar	feat;
+
+	uvlong	sectors;
+	char	serial[20+1];
+	char	firmware[8+1];
+	char	model[40+1];
+	char	ident[0x100];
+};
+
+static	Ctlr	*head;
+static	Ctlr	*tail;
+
+static	int	aoeether[10];
+
+SDifc sdaoeifc;
+
+static void
+hnputs(uchar *p, ushort i)
+{
+	p[0] = i >> 8;
+	p[1] = i;
+}
+
+static void
+hnputl(uchar *p, ulong i)
+{
+	p[0] = i >> 24;
+	p[1] = i >> 16;
+	p[2] = i >> 8;
+	p[3] = i;
+}
+
+static ushort
+nhgets(uchar *p)
+{
+	return *p<<8 | p[1];
+}
+
+static ulong
+nhgetl(uchar *p)
+{
+	return p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
+}
+
+static int
+newtag(Ctlr *d)
+{
+	int t;
+
+	for(;;){
+		t = ++d->lasttag << 16;
+		t |= m->ticks & 0xffff;
+		switch(t) {
+		case Tfree:
+		case Tmgmt:
+			break;
+		default:
+			return t;
+		}
+	}
+}
+
+static int
+hset(Ctlr *d, Aoehdr *h, int cmd)
+{
+	int tag;
+
+	memmove(h->dst, d->ea, Eaddrlen);
+	hnputs(h->type, Aoetype);
+	h->verflag = Aoever << 4;
+	hnputs(h->major, d->major);
+	h->minor = d->minor;
+	h->cmd = cmd;
+	hnputl(h->tag, tag = newtag(d));
+	return tag;
+}
+
+static void
+idmove(char *p, ushort *a, int n)
+{
+	int i;
+	char *op, *e;
+
+	op = p;
+	for(i = 0; i < n / 2; i++){
+		*p++ = a[i] >> 8;
+		*p++ = a[i];
+	}
+	*p = 0;
+	while(p > op && *--p == ' ')
+		*p = 0;
+	e = p;
+	p = op;
+	while(*p == ' ')
+		p++;
+	memmove(op, p, n - (e - p));
+}
+
+static ushort
+gbit16(void *a)
+{
+	uchar *i;
+
+	i = a;
+	return i[1]<<8 | i[0];
+}
+
+static u32int
+gbit32(void *a)
+{
+	uchar *i;
+	u32int j;
+
+	i = a;
+	j  = i[3] << 24;
+	j |= i[2] << 16;
+	j |= i[1] << 8;
+	j |= i[0];
+	return j;
+}
+
+static uvlong
+gbit64(void *a)
+{
+	uchar *i;
+
+	i = a;
+	return (uvlong)gbit32(i+4) << 32 | gbit32(a);
+}
+
+static int
+ataidentify(Ctlr *c, ushort *id)
+{
+	vlong s;
+	int i;
+
+	i = gbit16(id+83) | gbit16(id+86);
+	if(i & (1 << 10)){
+		c->feat |= Dllba;
+		s = gbit64(id+100);
+	}else
+		s = gbit32(id+60);
+
+	idmove(c->serial, id+10, 20);
+	idmove(c->firmware, id+23, 8);
+	idmove(c->model, id+27, 40);
+
+print("aoe discovers %d.%d: %s %s\n", c->major, c->minor, c->model, c->serial);
+
+	c->sectors = s;
+	c->mediachange = 1;
+	return 0;
+}
+
+static void
+identifydump(Aoeata *a)
+{
+	print("%E %E type=%.4ux verflag=%x error=%x %d.%d cmd=%d tag=%.8lux\n",
+		a->dst, a->src, nhgets(a->type), a->verflag, a->error,
+		nhgets(a->major), a->minor, a->cmd, nhgetl(a->tag));
+	print("   aflag=%x errfeat=%ux scnt=%d cmdstat=%ux, lba=%d? res=%.4ux\n",
+		a->aflag, a->errfeat, a->scnt, a->cmdstat, 0, nhgets(a->res));
+}
+
+static int
+idpkt(Ctlr *c, Aoeata *a)
+{
+	memset(a, 0, sizeof *a);
+	a->cmdstat = Cid;
+	a->scnt = 1;
+	a->lba[3] = 0xa0;
+	return hset(c, a, ACata);
+}
+
+static int
+chktag(int *out, int nout, int tag)
+{
+	int j;
+
+	for(j = 0; j <= nout; j++)
+		if(out[j] == tag)
+			return 0;
+print("wrong tag\n");
+	for(j = 0; j <= nout; j++)
+		print("%.8ux != %.8ux\n", out[j], tag);
+	return -1;
+}
+
+/*
+ * ignore the tag for identify.  better than ignoring
+ * a response to the wrong identify request
+ */
+static int
+identify(Ctlr *c)
+{
+	int tag[5], i, n;
+	Aoeata *a;
+	Etherpkt p;
+
+	memset(&p, 0, sizeof p);
+	a = (Aoeata*)&p;
+	i = 0;
+	do {
+		if(i == 5){
+			print("aoe: identify timeout\n");
+			return -1;
+		}
+		tag[i] = idpkt(c, a);
+		ethertxpkt(c->ctlrno, &p, sizeof *a, 0);
+		memset(&p, 0, sizeof p);
+next:
+		n = etherrxpkt(c->ctlrno, &p, 125);
+		if(n == 0){
+			i++;
+			continue;
+		}
+		if(nhgets(a->type) != Aoetype)
+			goto next;
+		if(nhgets(a->major) != c->major || a->minor != c->minor){
+			print("wrong device %d.%d want %d.%d; %d\n",
+				nhgets(a->major), a->minor,
+				c->major, c->minor, n);
+			goto next;
+		}
+		if(chktag(tag, i, nhgetl(a->tag)) == -1)
+			goto next;
+		if(a->cmdstat & 0xa9){
+			print("aoe: ata error on identify: %2ux\n", a->cmdstat);
+			return -1;
+		}
+	} while (a->scnt != 1);
+
+	c->feat = 0;
+	ataidentify(c, (ushort*)(a+1));
+	return 0;
+}
+
+static Ctlr*
+ctlrlookup(int major, int minor)
+{
+	Ctlr *c;
+
+	for(c = head; c; c = c->next)
+		if(c->major == major && c->minor == minor)
+			break;
+	return c;
+}
+
+static Ctlr*
+newctlr(Etherpkt *p)
+{
+	int major, minor;
+	Aoeqc *q;
+	Ctlr *c;
+
+	q = (Aoeqc*)p;
+	if(nhgets(q->type) != Aoetype)
+		return 0;
+	major = nhgets(q->major);
+	minor = q->minor;
+
+	if(major == 0xffff || minor == 0xff)
+		return 0;
+
+	if(ctlrlookup(major, minor)){
+		print("duplicate shelf.slot\n");
+		return 0;
+	}
+
+	if((c = malloc(sizeof *c)) == 0)
+		return 0;
+	c->major = major;
+	c->minor = minor;
+	memmove(c->ea, q->src, Eaddrlen);
+
+	if(head != 0)
+		tail->next = c;
+	else
+		head = c;
+	tail = c;
+	return c;
+}
+
+static void
+discover(int major, int minor)
+{
+	int i;
+	Aoehdr *h;
+	Etherpkt p;
+
+	for(i = 0; i < nelem(aoeether); i++){
+		if(aoeether[i] == 0)
+			continue;
+		memset(&p, 0, ETHERMINTU);
+		h = (Aoehdr*)&p;
+		memset(h->dst, 0xff, sizeof h->dst);
+		hnputs(h->type, Aoetype);
+		h->verflag = Aoever << 4;
+		hnputs(h->major, major);
+		h->minor = minor;
+		h->cmd = ACconfig;
+		ethertxpkt(i, &p, ETHERMINTU, 0);
+	}
+}
+
+static int
+rxany(Etherpkt *p, int t)
+{
+	int i, n;
+
+	for(i = 0; i < nelem(aoeether); i++){
+		if(aoeether[i] == 0)
+			continue;
+		while ((n = etherrxpkt(i, p, t)) != 0)
+			if(nhgets(p->type) == Aoetype)
+				return n;
+	}
+	return 0;
+}
+
+static int
+aoeprobe(int major, int minor, SDev *s)
+{
+	Ctlr *ctlr;
+	Etherpkt p;
+	int n, i;
+
+	for(i = 0;; i += 200){
+		if(i > 8000)
+			return -1;
+		discover(major, minor);
+again:
+		n = rxany(&p, 100);
+		if(n > 0 && (ctlr = newctlr(&p)))
+			break;
+		if(n > 0)
+			goto again;
+	}
+
+	s->ctlr = ctlr;
+	s->ifc = &sdaoeifc;
+	s->nunit = 1;
+	return 0;
+}
+
+static char 	*probef[32];
+static int 	nprobe;
+
+int
+pnpprobeid(char *s)
+{
+	int id;
+
+	if(strlen(s) < 2)
+		return 0;
+	id = 'e';
+	if(s[1] == '!')
+		id = s[0];
+	return id;
+}
+
+int
+tokenize(char *s, char **args, int maxargs)
+{
+	int nargs;
+
+	for(nargs = 0; nargs < maxargs; nargs++){
+		while(*s != '\0' && strchr("\t\n ", *s) != nil)
+			s++;
+		if(*s == '\0')
+			break;
+		args[nargs] = s;
+		while(*s != '\0' && strchr("\t\n ", *s) == nil)
+			s++;
+		if(*s != '\0')
+			*s++ = 0;
+	}
+	return nargs;
+}
+
+int
+aoepnp0(void)
+{
+	int i;
+	char *p, c;
+
+	if((p = getconf("aoeif")) == nil)
+		return 0;
+print("aoeif = %s\n", p);
+	nprobe = tokenize(p, probef, nelem(probef));
+	for(i = 0; i < nprobe; i++){
+		if(strncmp(probef[i], "ether", 5) != 0)
+			continue;
+		c = probef[i][5];
+		if(c > '9' || c < '0')
+			continue;
+		aoeether[c - '0'] = 1;
+	}
+
+	if((p = getconf("aoedev")) == nil)
+		return 0;
+	return nprobe = tokenize(p, probef, nelem(probef));
+}
+
+int
+probeshelf(char *s, int *shelf, int *slot)
+{
+	int a, b;
+	char *r;
+
+	for(r = s + strlen(s) - 1; r > s; r--)
+		if((*r < '0' || *r > '9') && *r != '.'){
+			r++;
+			break;
+		}
+	a = strtoul(r, &r, 10);
+	if(*r++ != '.')
+		return -1;
+	b = strtoul(r, 0, 10);
+
+	*shelf = a;
+	*slot = b;
+print("  shelf=%d.%d\n", a, b);
+	return 0;
+}
+
+Ctlr*
+pnpprobe(SDev *sd)
+{
+	int shelf, slot;
+	char *p;
+	static int i;
+
+	if(i >= nprobe)
+		return 0;
+	p = probef[i++];
+	if(strlen(p) < 2)
+		return 0;
+	if(p[1] == '!'){
+		sd->idno = p[0];
+		p += 2;
+	}
+	if(probeshelf(p, &shelf, &slot) == -1 ||
+	    aoeprobe(shelf, slot, sd) == -1 ||
+	    identify(sd->ctlr) == -1)
+		return 0;
+	return sd->ctlr;
+}
+
+/*
+ * we may need to pretend we found something
+ */
+
+SDev*
+aoepnp(void)
+{
+	int n, i, id;
+	char *p;
+	SDev *h, *t, *s;
+
+	p = getconf("aoeif");
+	if (p)
+		print("aoepnp: aoeif=%s\n", p);
+
+	if((n = aoepnp0()) == 0)
+		n = 2;
+	t = h = 0;
+	for(i = 0; i < n; i++){
+		id = 'e';
+		s = malloc(sizeof *s);
+		if(s == 0)
+			break;
+		s->ctlr = 0;
+		s->idno = id;
+		s->ifc = &sdaoeifc;
+		s->nunit = 1;
+		pnpprobe(s);
+
+		if(h)
+			t->next = s;
+		else
+			h = s;
+		t = s;
+	}
+	return h;
+}
+
+static int
+aoeverify(SDunit *u)
+{
+	Ctlr *c;
+	SDev *s;
+
+	s = u->dev;
+	c = s->ctlr;
+	if(c == 0){
+		aoepnp0();
+		if((s->ctlr = c = pnpprobe(s)) == nil)
+			return 0;
+	}
+	c->mediachange = 1;
+	return 1;
+}
+
+static int
+aoeonline(SDunit *u)
+{
+	int r;
+	Ctlr *c;
+
+	c = u->dev->ctlr;
+	if(c->mediachange){
+		r = 2;
+		c->mediachange = 0;
+		u->sectors = c->sectors;
+		u->secsize = 512;
+	} else
+		r = 1;
+	return r;
+}
+
+static int
+rio(Ctlr *c, Aoeata *a, int n, int scnt)
+{
+	int i, tag, cmd;
+
+	for(i = 0; i < 5; i++){
+		tag = hset(c, a, ACata);
+		cmd = a->cmdstat;
+		ethertxpkt(c->ctlrno, (Etherpkt*)a, n, 0);
+		memset(a, 0, sizeof *a);
+again:
+		n = etherrxpkt(c->ctlrno, (Etherpkt*)a, 125);
+		if(n == 0)
+			continue;
+		if(nhgets(a->type) != Aoetype || nhgetl(a->tag) != tag ||
+		    nhgets(a->major) != c->major || a->minor != c->minor)
+			goto again;
+		if(a->cmdstat & 0xa9){
+			print("aoe: ata rio error: %2ux\n", a->cmdstat);
+			return 0;
+		}
+		switch(cmd){
+		case Crd:
+		case Crdext:
+			if(n - sizeof *a < scnt * 512){
+				print("aoe: runt expect %d got %d\n",
+					scnt*512 + sizeof *a, n);
+				return 0;
+			}
+			return n - sizeof *a;
+		case Cwr:
+		case Cwrext:
+			return scnt * 512;
+		default:
+print("unknown cmd %ux\n", cmd);
+			break;
+		}
+	}
+	print("aoe: rio timeout\n");
+	return 0;
+}
+
+static void
+putlba(Aoeata *a, vlong lba)
+{
+	uchar *c;
+
+	c = a->lba;
+	c[0] = lba;
+	c[1] = lba >> 8;
+	c[2] = lba >> 16;
+	c[3] = lba >> 24;
+	c[4] = lba >> 32;
+	c[5] = lba >> 40;
+}
+
+/*
+ * you'll need to loop if you want to read more than 2 sectors.  for now
+ * i'm cheeting and not bothering with a loop.
+ */
+static uchar pktbuf[1024 + sizeof(Aoeata)];
+
+static int
+aoebuild(Ctlr *c, uchar *cmd, char *data, vlong lba, int scnt)
+{
+	int n;
+	Aoeata *a;
+
+	memset(pktbuf, 0, sizeof pktbuf);
+	a = (Aoeata*)pktbuf;
+	hset(c, a, ACata);
+	putlba(a, lba);
+
+	a->cmdstat = 0x20;
+	if(c->flag & Dllba){
+		a->aflag |= AAFext;
+		a->cmdstat |= 4;
+	}else{
+		a->lba[3] &= 0xf;
+		a->lba[3] |= 0xe0;		/* LBA bit+obsolete 0xa0 */
+	}
+
+	n = scnt;
+	if(n > 2)
+		n = 2;
+	a->scnt = n;
+
+	switch(*cmd){
+	case 0x2a:
+		a->aflag |= AAFwrite;
+		a->cmdstat |= 10;
+		memmove(a+1, data, n*512);
+		n = sizeof *a + n*512;
+		break;
+	case 0x28:
+		n = sizeof *a;
+		break;
+	default:
+		print("aoe: bad cmd 0x%.2ux\n", cmd[0]);
+		return -1;
+	}
+	return n;
+}
+
+static int
+aoerio(SDreq *r)
+{
+	int size, nsec, n;
+	vlong lba;
+	char *data;
+	uchar *cmd;
+	Aoeata *a;
+	Ctlr *c;
+	SDunit *unit;
+
+	unit = r->unit;
+	c = unit->dev->ctlr;
+	if(r->data == nil)
+		return SDok;
+	cmd = r->cmd;
+
+	lba = cmd[2]<<24 | cmd[3]<<16 | cmd[4]<<8 | cmd[5];	/* sic. */
+	nsec = cmd[7]<<8 | cmd[8];
+	a = (Aoeata*)pktbuf;
+	data = r->data;
+	r->rlen = 0;
+
+	for(; nsec > 0; nsec -= n){
+//		print("aoebuild(%2x, %p, %lld, %d)\n", *cmd, data, lba, nsec);
+		size = aoebuild(c, cmd, data, lba, nsec);
+		if(size < 0){
+			r->status = SDcheck;
+			return SDcheck;
+		}
+		n = a->scnt;
+		r->rlen += rio(c, a, size, n);
+		if(*cmd == 0x28)
+			memmove(r->data, a + 1, n * 512);
+		data += n * 512;
+		lba += n;
+	}
+
+	r->status = SDok;
+	return SDok;
+}
+
+SDifc sdaoeifc = {
+	"aoe",
+
+	aoepnp,
+	nil,		/* legacy */
+	nil,		/* id */
+	nil,		/* enable */
+	nil,		/* disable */
+
+	aoeverify,
+	aoeonline,
+	aoerio,
+	nil,
+	nil,
+
+	scsibio,
+};

+ 159 - 0
sys/src/boot/pc/sdbios.c

@@ -0,0 +1,159 @@
+/*
+ * boot driver for BIOS devices with partitions
+ * devbios must be called first
+ */
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "ureg.h"
+#include "error.h"
+
+#include "sd.h"
+#include "fs.h"
+
+long	biosread(Fs *, void *, long);
+vlong	biosseek(Fs *fs, vlong off);
+
+extern SDifc sdbiosifc;
+
+int
+biosverify(SDunit* )
+{
+	return 1;
+}
+
+int
+biosonline(SDunit* unit)
+{
+	if (!unit)
+		return 0;
+	unit->sectors = 1UL << 30;	/* a bunch */
+	unit->secsize = 512;		/* conventional */
+	return 1;
+}
+
+static int
+biosrio(SDreq* r)
+{
+	int nb;
+	long got;
+	vlong len, off;
+	uchar *p;
+	Fs fs;			/* just for fs->dev, which is zero */
+
+	/*
+	 * Most SCSI commands can be passed unchanged except for
+	 * the padding on the end. The few which require munging
+	 * are not used internally. Mode select/sense(6) could be
+	 * converted to the 10-byte form but it's not worth the
+	 * effort. Read/write(6) are easy.
+	 */
+	r->rlen = 0;
+	r->status = SDok;
+	switch(r->cmd[0]){
+	case 0x08:			/* read */
+	case 0x28:			/* read */
+		if (r->cmd[0] == 0x08)
+			panic("biosrio: 0x08 read op\n");
+		off = r->cmd[2]<<24 | r->cmd[3]<<16 | r->cmd[4]<<8 | r->cmd[5];
+		nb = r->cmd[7]<<8 | r->cmd[8];	/* often 4 */
+		USED(nb);		/* is nb*512 == r->dlen? */
+		memset(&fs, 0, sizeof fs);
+		biosseek(&fs, off*512);
+		got = biosread(&fs, r->data, r->dlen);
+		if (got < 0)
+			r->status = SDeio;
+		else
+			r->rlen = got;
+		break;
+	case 0x0A:			/* write */
+	case 0x2A:			/* write */
+		r->status = SDeio;	/* boot programs don't write */
+		break;
+	case 0x25:			/* read capacity */
+		/*
+		 * Read capacity returns the LBA of the last sector.
+		 */
+		len = r->unit->sectors - 1;
+		p = r->data;
+		*p++ = len>>24;
+		*p++ = len>>16;
+		*p++ = len>>8;
+		*p++ = len;
+		len = r->unit->secsize;
+		*p++ = len>>24;
+		*p++ = len>>16;
+		*p++ = len>>8;
+		*p = len;
+		r->data = (char *)r->data + 8;
+		return SDok;
+	case 0x9E:			/* long read capacity */
+		/*
+		 * Read capacity returns the LBA of the last sector.
+		 */
+		len = r->unit->sectors - 1;
+		p = r->data;
+		*p++ = len>>56;
+		*p++ = len>>48;
+		*p++ = len>>40;
+		*p++ = len>>32;
+		*p++ = len>>24;
+		*p++ = len>>16;
+		*p++ = len>>8;
+		*p++ = len;
+		len = r->unit->secsize;
+		*p++ = len>>24;
+		*p++ = len>>16;
+		*p++ = len>>8;
+		*p = len;
+		r->data = (char *)r->data + 8;
+		return SDok;
+	/* ignore others */
+	}
+	return r->status;
+}
+
+SDev*
+biosid(SDev* sdev)
+{
+	for (; sdev; sdev = sdev->next)
+		if (sdev->ifc == &sdbiosifc)
+			sdev->idno = 'B';
+	return sdev;
+}
+
+static SDev*
+biospnp(void)
+{
+	SDev *sdev;
+
+	if (pxe)
+		return nil;
+	if((sdev = malloc(sizeof(SDev))) != nil) {
+		sdev->ifc = &sdbiosifc;
+		sdev->index = -1;
+		sdev->nunit = 1;
+	}
+	return sdev;
+}
+
+SDifc sdbiosifc = {
+	"bios",				/* name */
+
+	biospnp,			/* pnp */
+	nil,				/* legacy */
+	biosid,				/* id */
+	nil,				/* enable */
+	nil,				/* disable */
+
+	biosverify,			/* verify */
+	biosonline,			/* online */
+	biosrio,			/* rio */
+	nil,				/* rctl */
+	nil,				/* wctl */
+
+	scsibio,			/* bio */
+};