Date: Tue, 9 Jan 1996 20:25:11 +0100 (MET) From: J Wunsch <j@ida.interface-business.de> To: freebsd-scsi@freebsd.org Subject: More CD-R news Message-ID: <199601091925.UAA01102@ida.interface-business.de>
next in thread | raw e-mail | index | archive | help
Well, i've finally got the first successfully burnt CD.
Here's a bit more about the equipment:
. The burner is a:
(ahc1:0:0): "PLASMON RF4100 1.28" type 4 removable SCSI 2
It has 2 MB cache, and burns @ 360 KB/s.
. There were still some show-stoppers in the driver, i will cleanup
and commit the fixes RSN. The most annoying show-stopper was the CD
block count limitation, that didn't account for the CD blocks being
2048 bytes long, while the struct buf blocks are DEV_BSIZE long, so
one of my attempts ended up prematurely since the driver thought the
CD were full while it was only 1/4 filled. :(
. Before running the successful burn, i've made a couple of dummy
burns (pretend a burn, but don't actually turn on the laser). I've
been using one of them as a ``load test'', to see how much i could
do on the machine while the CD writing was in progress. The machine
is an i486/100 with (only) 16 MB RAM, and 2 AHA2940s. One of the
controllers is dedicated to the hard disk, the other one drives a
CD-ROM, a DAT tape, and the CD-R. The actual driver for burning the
CD is a combination of team(1) and dd(1). Team is used in order to
have a multiplexed disk read / pipe write utility that serves as a
user-program cache. I ran team with 5 processes and one MB buffer
for each of them. Top shows that the processes actually account for
about 1 MB RSS, so this seems to work as expected. The dd was
needed in order to `slice' team's output stream into multiples of
the blocksize of the CD (i've used 10 * blocksize). This is not as
much a problem for data CDs, but would really be necessary when it
comes to audio CDs which have a blocksize of 2352 bytes. Team ran
with `rtprio', in order to increase its probability to get the
required resources.
. The load test consisted of running the entire dummy burn running
under X11 in the normal multi-user environment. Everything went
fine, including a minor test compilation (about 5 smaller C sources,
linked together with a bunch of X11 libs), and running `beforelight'
as the screen saver (which even under normal circumstances tends to
cause larger paging activity when the screen saver becomes active,
or when it's de-activated). The average swap usage levelled about
33 MB. :) The test burn finally starved (CD-R write buffer underrun)
when one of my colleages piped a larger PostScript file through lpd,
not thinking of the fact that the ghostscript converter would also
ran on my PC. :--) Anyway, this seems to be not too bad. I've made
another test run after this, without X11, and this one even survived
the ghostscript test. ;-)
. After all these tests, the `hot' run was rather unimpressive. Still
full multiuser, no X11, but i used to do some regular user activity
from the text consoles (login, elm, rlogin, rcp), without affecting
the CD-R too much. It finally completed to burn 460 MB of test data
after 1500 seconds.
Now back to thinking about the worm driver architecture. :)
p.s.: Just to provide an impression about what's needed to burn a CD,
here's the Perl script:
#!/usr/bin/perl
#
$ENV{'PATH'} = "/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin";
# For FreeBSD <= 2.1, the control device didn't work, use the regular
# device:
##$wormctl = "/dev/rworm0";
$wormctl = "/dev/rworm0.ctl";
$wormdata = "/dev/rworm0";
# set dummy to yes if the command should be faked
#$dummy = "yes";
$dummy = "no";
$verbose = 1;
$mode = "data";
$preempt = 0;
$toc_type = "ROM";
# timeouts
$medium = 30;
$long = 10 * 60;
$bsize_data = 2048;
$bsize_audio = 2352;
# direct SCSI operations
sub test_unit_ready
{
$verbose && print "test_unit_ready\n";
system ("scsi", "-f", $wormctl, "-c", "0 0 0 0 0 0") &&
die "scsi failed\n";
}
sub clear_unit_attn
{
$verbose && print "clear_unit_attn\n";
# test unit ready with stderr supressed
if(fork == 0) {
close STDOUT;
close STDERR;
close STDIN;
exec "scsi", "-f", $wormctl, "-c", "0 0 0 0 0 0";
} else {
wait;
}
}
sub rezero_unit
{
$verbose && print "rezero_unit\n";
system ("scsi", "-s", $medium, "-f", $wormctl, "-c", "1 0 0 0 0 0") &&
die "scsi failed\n";
}
sub start_stop
{
local($start) = @_;
$verbose && printf "start_stop(%d)\n", $start;
system ("scsi", "-s", $medium, "-f", $wormctl,
"-c", "1b 0 0 0 0:b7 v:b1 0",
$start? "1": "0") &&
die "scsi failed\n";
}
sub synchronize_cache
{
$verbose && print "synchronize_cache\n";
system ("scsi", "-s", $medium, "-f", $wormctl,
"-c", "35 0 v:i4 0 v:i2 0", "0", "0") &&
die "scsi failed\n";
}
sub prevent_allow_medium_removal
{
local($prevent) = @_;
$verbose && printf "prevent_allow_medium_removal(%d)\n", $prevent;
system ("scsi", "-f", $wormctl,
"-c", "1e 0 0 0 0:b7 v:b1 0",
$prevent? "1": "0") &&
die "scsi failed\n";
}
sub fixation
{
local($toc_type) = @_;
$verbose && printf "fixation(%s)\n", $toc_type;
system ("scsi", "-s", $long, "-f", $wormctl,
"-c", "e9 0 0 0 0 0 0 0 0:b4 v:b1 v:b3 0", "0",
$toc_type eq "ROM"? "1": "0") &&
die "scsi failed\n";
}
sub recover
{
system ("scsi", "-s", $medium, "-f", $wormctl,
"-c", "ec 0 0 0 0 0 0 0 0 0") &&
die "scsi failed\n";
}
sub reserve_track
{
local($len) = @_;
system ("scsi", "-f", $wormctl,
"-c", "e4 0 0 0 0 v:i4 0", "$len") &&
die "scsi failed\n";
}
sub write_track
{
local($audio, $preemp) = @_;
local($x);
$verbose && printf "write_track(%s, %d)\n", $audio, $preemp;
if($audio eq "audio") { $x = $preemp? "5": "4"; }
else { $x = "1"; }
system ("scsi", "-f", $wormctl,
"-c", "e6 0 0 0 0 v:i1 0:b4 v:b4 0 0 0", "0", $x) &&
die "scsi failed\n";
}
sub load_unload
{
local($load) = @_;
$verbose && printf "load_unload(%d)\n", $load;
system ("scsi", "-s", $medium, "-f", $wormctl,
"-c", "e7 0 0 0 0 0 0 0 0:b7 v:b1 0",
$load? "0": "1") &&
die "scsi failed\n";
}
sub per_disk_select
{
local($dummy, $speed) = @_;
$verbose && printf "per_disk_select(%s, %s)\n", $dummy, $speed;
system ("scsi", "-f", $wormctl,
"-c", "15 0:b3 v:b1 0:b3 v:b1 0 0 0c 0", "1", "0",
"-o", "12", "0 0 0 0 23 06 v:i1 v:i1 0 0 0 0",
$speed eq "audio"? "1": "2",
$dummy eq "yes"? "1": "0") &&
die "scsi failed\n";
}
sub per_track_select
{
local($audio, $preemp) = @_;
local($x, $blksiz);
$verbose && printf "per_track_select(%s, %d)\n", $audio, $preemp;
if($audio eq "audio") { $blksiz = "2352"; $x = $preemp? "5": "4"; }
else { $blksiz = "2048"; $x = "1"; }
system ("scsi", "-f", $wormctl,
"-c", "15 0:b3 v:b1 0:b3 v:b1 0 0 1c 0", "1", "0",
"-o", "28",
"0 0 0 8 0 v:i3 0 v:i3 21 0e 0 0:b4 v:b4 0 0 0 0 0 0 0 0 0 0 0 0",
"0", $blksiz, $x) &&
die "scsi failed\n";
}
die "usage: $0 inputfile\n" unless $#ARGV == 0;
die "Must be root to run this\n" unless $< == 0;
print "Preparing unit\n";
&clear_unit_attn;
&load_unload(1);
&clear_unit_attn;
&prevent_allow_medium_removal(1);
&start_stop(1);
&rezero_unit;
&test_unit_ready;
&start_stop(1);
&per_disk_select($dummy, $mode);
print "Preparing track\n";
&per_track_select($mode, 0);
#&reserve_track(0);
#&write_track($mode, 0);
print "Writing track\n";
$bsize = $mode eq "audio"? $bsize_audio: $bsize_data;
$bsize *= 10;
#system "dd", "if=$ARGV[0]", "of=$wormdata", "obs=$bsize", "conv=sync";
system "rtprio 5 team -v 1m 5 < $ARGV[0] | dd of=$wormdata obs=$bsize";
&synchronize_cache;
if($dummy ne "yes") {
print "Fixating\n";
&fixation($toc_type);
}
print "Stopping\n";
&start_stop(0);
&prevent_allow_medium_removal(0);
&load_unload(0);
print "Done.\n";
--
J"org Wunsch Unix support engineer
joerg_wunsch@interface-business.de
[private: http://www.sax.de/~joerg/]
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199601091925.UAA01102>
