From owner-freebsd-scsi Tue Jan 9 11:25:47 1996 Return-Path: owner-freebsd-scsi Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id LAA00279 for freebsd-scsi-outgoing; Tue, 9 Jan 1996 11:25:47 -0800 (PST) Received: from innocence.interface-business.de (innocence.interface-business.de [193.101.57.101]) by freefall.freebsd.org (8.7.3/8.7.3) with ESMTP id LAA00271 for ; Tue, 9 Jan 1996 11:25:34 -0800 (PST) Received: from ida.interface-business.de (ida.interface-business.de [193.101.57.203]) by innocence.interface-business.de (8.6.11/8.6.9) with ESMTP id UAA19760 for ; Tue, 9 Jan 1996 20:27:12 +0100 Received: (from j@localhost) by ida.interface-business.de (8.6.11/8.6.9) id UAA01102 for freebsd-scsi@freebsd.org; Tue, 9 Jan 1996 20:25:13 +0100 From: J Wunsch Message-Id: <199601091925.UAA01102@ida.interface-business.de> Subject: More CD-R news To: freebsd-scsi@freebsd.org Date: Tue, 9 Jan 1996 20:25:11 +0100 (MET) Reply-To: joerg_wunsch@interface-business.de (Joerg Wunsch) X-Phone: +49-351-31809-14 X-Fax: +49-351-3361187 X-Mailer: ELM [version 2.4 PL23] MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Sender: owner-freebsd-scsi@freebsd.org Precedence: bulk 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/]