README for the SCSI media changer driver
========================================

This is a driver for SCSI Medium Changer devices, which are listed
with "Type: Medium Changer" in /proc/scsi/scsi.

This is for *real* Jukeboxes.  It is *not* supported to work with
common small CD-ROM changers, neither one-lun-per-slot SCSI changers
nor IDE drives.

I'll upload scsi-changer only to sunsite, if I feel it is a stable
release.  To check for the very last version, point your Browser to
	http://www.in-berlin.de/User/kraxel/linux.html


General Information
-------------------

First some words about how changers work: A changer has 2 (possibly
more) SCSI ID's. One for the changer device which controls the robot,
and one for the device which actually reads and writes the data. The
later may be anything, a MOD, a CD-ROM, a tape or whatever. For the
changer device this is a "don't care", he *only* shuffles around the
media, nothing else.


The SCSI changer model is complex, compared to - for example - IDE-CD
changers. But it allows to handle nearly all possible cases. It knows
4 different types of changer elements:

  media transport - this one shuffles around the media, i.e. the
                    transport arm
  storage         - a slot which can hold a media.
  import/export   - the same as above, but is accessable from outside,
                    i.e. there the operator (you !) can use this to
                    fill in and remove media from the changer.
  data transfer   - this is the device which reads/writes.

None of these is limited to one: A huge Jukebox could have slots for
123 CD-ROM's, 5 CD-ROM readers (and therefore 6 SCSI ID's: the changer
and each CD-ROM) and 2 transport arms. No problem to handle.


How it is implemented
---------------------

I implemented the driver as character device driver with a NetBSD-like
ioctl interface. Just grabbed NetBSD's header file and one of the
other linux SCSI device drivers as starting point. The interface
should be source code compatible with NetBSD. So if there is any
software (anybody knows ???) which supports a BSDish changer driver,
it should work with this driver too.


Current State
-------------

Most ioctl's are implemented and should work. Support for more than
one transport arm is not implemented (yet). You should take the code
as beta quality, there are probably some bugs.  Currently the driver
is distributed as loadable module for the 2.0.x and 2.1.x kernels.

I got some reports telling it works ok with tape autoloaders (Exabyte,
HP and DEC). Some People use this driver with amanda. It works fine
with small (11 slots) and a huge (4 MOs, 88 slots) magneto-optical
Jukebox too. Probably with other changers too, most (but not all :-)
people mail me only if it does *not* work...


Compiling the package
---------------------

A simple 'make' should do the trick. It produces some warnings (four in
2.0.x, three in 2.1.x), that's ok. If make fails:
  - make sure you have a configured 2.0.x kernel source tree in
    /usr/src/linux. If it sit's somewhere else, edit the Makefile. The
    kernel sources are required, becauce I use some makefile magic to
    compile the module with the same compiler switches which are used
    for compiling the kernel. This avoids trouble with some
    module/kernel config options (modversions+SMP). And theoretical it
    should work even on Linux/alpha without changes...
    [ and actually does work on my new SparcLinux box :-) ]
  - make sure you have a symlink from /usr/include/scsi to
    /usr/src/linux/include/scsi
  - make sure gcc, binutils and modutils are not too old (check
    /usr/src/linux/Documentation/Changes for details).

After compiling you should have the following files:

  ch.o     - the driver as loadable kernel module
  userland - a small program for testing the driver / sending commands
             to the changer
  unload   - a even smaller program to send a eject to any SCSI device
  load     - (symlink to unload) sends a load instead of eject.


Using it
--------

There is a small script 'MAKEDEV.sch', creates the new special
file /dev/sch0 ans /dev/sch1 for the changer. The driver has to be
loaded with insmod. If you want, you can copy the module to
/lib/modules/`uname -r`/scsi and let kerneld load it. Add
'alias char-major-86 ch' to /etc/conf.modules to make this work.

If the module finds the changer, it prints some messages about the
device [ try "dmesg" if you don't see anything ] and should show up in
/proc/devices. If not....  some changers use ID ? / LUN 0 for the
device and ID ? / LUN 1 for the robot mechanism. But Linux does *not*
look for LUN's other than 0 as default, becauce there are to many
broken devices. So you can try:

  1) echo "scsi add-single-device 0 0 ID 1" > /proc/scsi/scsi
     (replace ID with the SCSI-ID of the device)
  2) boot the kernel with "max_scsi_luns=1" on the command line
     (append="max_scsi_luns=1" in lilo.conf should do the trick)


userland (had no better name idea) is the program for talking with the
driver. Calling userland without args should print how much elements
of each type the changer has and the current status bits of every
element. The status bits are:

  - full    set if the element holds a media
  - access  set if the changer can or is allowed to access the
            element. If this bit is not set for the data transfer
            element, you'll probably have to use eject it first using
            the unload program.
  - except  exception - something went really wrong.

import/export elements have a few more:

  - inenab  set if the element can import media
  - exenab  set if the element can export media
  - impexp  set if the media in the element has been inserted from outside


To shuffle around media you can give userland some args
  userland mv <src> <dest> [rotate]
  userland ex <src> <dest1> <dest2> [rotate]

src and dest are a letter/number combination. The letter is the element
type (t,s,e or d) and the number is the number of the element,
numbering start with zero. "s4" is slot #5, "d0" the read/write
device, ...   Hope you get the idea.

"mv" simply moves the media from src to dest, "ex" moves media1 from src
to dest1, and media2 from dest1 to dest2. The scsi standard allows src and
dest2 to address the same element (i.e. perform a swap). 

Rotate is a bit field for rotating the media while moving it. "mv"
uses bit 0 only, so say "1" here to rotate the media, "0" (or omitting
the argument) to not rotate it. "ex" uses bit 0 for media1, bit 1 for
media2, so "2" would rotate media 2, "3" would rotate both. Of cource
this works only for double-sided media, some MO changers for example.

You can position the transport arm in front of a element with
  userland pos <elem> [rotate]
Syntax for elem and rotate as above.

Note that the POSITION TO ELEMENT ("pos") and EXCHANGE MEDIUM ("ex")
commands are marked optional in the SCSI-II specs, so they may not
work due lack of support.

NEW: userland knows "load" and "unload" now. "load n" moves media from
slot n to the first (and often only) data transfer element, and
"unload n" does the reverse. So "load 1" is an alias for "mv s1 d0",
just to make life a bit easier.  "unload" without an argument should
put the media back to the slot where it came from.

With
  userland info <elem> 
you can ask for detailed informations about a element. 


The unload program can be used to unload (eject) and load any
removeable SCSI media. It takes a device as argument, unlocks it and
sends a START STOP command. Without argument it uses the compiled-in
default device (there is a #define in the source to change this it you
want). It unloads if the program name is "unload", and loads else. 

unload can eject everything: CD-ROM, MOD, ZIP, whatelse. Even for tape
libraries this is useful: Most (all?) of them load the next tape in
order if you send a unload command to the tape device.

It is a quick & dirty hack, does not ask stupid questions or checks
anything. You can eject mounted media with it, so use it with care!
It requires root permissions, as the SCSI_IOCTL_SEND_COMMAND ioctl is
allowed for root only.


For MO / CD-ROM Jukeboxes there is now autofs support.  autojuke is a
"program map" (in autofs speak).  Startup:

  * Install it (for example) to /usr/sbin
  * copy the autojuke.conf file to /etc and edit it (see below for
    details)
  * fire up autofs with:
	/usr/sbin/automount /jukebox program /usr/sbin/autojuke

You should be able to change & mount media just by accessing
/jukebox/<slot-nr> or by accessing /jukebox/<volume-tag>. Error
messages show up in the syslog (/var/log/messages).  Only the
slot-nr thing is tested.

About the /etc/autojuke.conf file:
  * try_umount=0|1
    It is possible to signal the automound daemon (with SIGUSR1) it
    should umount idle devices.  If you set this to 1, autojuke will
    try this if there is no idle drive.  You probably want to use
    either this feature or a short timeout value for automount.
  * mopts=...
    specify mount options, autojuke passes them to the automount
    daemon.  Check out the automount manpage for details.
  * dev=special file
    specifies the special file(s) (/dev/something) of the data
    transfer elements.  There must be exactly one line per data
    transfer element.  autojuke uses this to look for idle drives
    (using /etc/mtab) and to tell automount which device it should
    mount. Order is important, the first line should address "d0",
    etc...

Note1: Volume tag support is optional for scsi media changers,
       therefore "cd /jukebox/<volume-tag>" might not work.
Note2: Currently there is no way to set volume tags, so the use of
       this feature is somewhat limited.
Note3: Support for double-sided media is'nt implemented yet...


Trouble?
--------

If you insmod the driver with "insmod debug=1", it will be verbose and
prints a lot of stuff to the syslog. You can display these messages with
the dmesg command (or check the logfiles). If you email me some question
becauce of a problem with the driver, please include these messages.


Porting
-------

People often ask how to port this to other OS'es (Solaris has most
hits currently :-). Well, the only OS I wrote device driver for is
linux, and I learned this by reading the source code, hacking, and
screwing up my box from time to time. So I can't tell if it is
possible (and if, how hard it is) to port the driver to another OS
or give some hints (Hmm, maybe wipe Solaris and install UltraPenguin
instead ?)

Porting the utility "userland" might be easy, if your OS has a scsi
changer driver. As mentioned above, I have stolen the ioctl-interface
from NetBSD. If you have a BSDish UN*X, chances are good that there
already is a changer driver which works with the userland utility.
Compiling it probably requires some header file fiddeling.

Another try worth is mtx, a extended mt program which can talk to scsi
changers too. People mention this in the news from time to time. Never
tried this, don't know whenever this is linux-specific or not. Grab it
from ftp://ftp.dandelion.com/mtx-1.0.tar.gz


Credits
-------

I wrote this driver using the famous mailing-patches-around-the-world
method. With (more or less) help from:

  Daniel Moehwald <moehwald@hdg.de>
  Dane Jasper <dane@sonic.net>
  R. Scott Bailey <sbailey@dsddi.eds.com>
  Jonathan Corbet <corbet@atd.ucar.edu>

Have fun!

--
Gerd Knorr <kraxel@goldbach.in-berlin.de>
