Skip site navigation (1)Skip section navigation (2)
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>