TODO:

1. Support binary data through the "-" mechanism.

2. Possibly add integrated Tcl/Tk support in the form of a wish shell
with the scsi library built in and not talking to it as a second program.
This will not be scsi(8) anymore because I don't want to increase
the footprint.

3. Clean up the code generation.  Possibly move all internals over
to SCSI CAM as Justin is going that way.

This is a work in progress.

This is a sketch release of a rewrite of scsi(8) to add commands
to the equivalent of the modes data base and to be better suited
for being driven by external programs.  It can also run as a daemon and
generate Tk data structures.  It includes a sample Tk
application that attempts to display the cylinder zones and defects
on a disk drive.  Note that Joerg reports the defect reading hangs
one of his drives, so be careful.

This new scsi(8) program adds these switches:

> scsi [-S style] -I               # To enter commands interactively
>       Supported styles: default, code, tcl
> scsi -C capfile                  # To load a cap file
>     "-C capfile" can occur as often as you want.
> scsi -D                          # To run as a daemon

-C Capfiles:

The program now tries to load both scsi_modes and scsi_caps.  These
files can now have entries such as:

> # ndefects plist glist
> ndefects "37 0 0:3 {plist} v:1 {vlist} v:1 5:3 0 0 0 0 4:i2 0" \
> -i 4 "*i2 {Defect list length} i2"
> 
> # defects plist glist size
> defects "37 0 0:3 {plist} v:1 {vlist} v:1 5:3 0 0 0 0 {xfer} v:i2 0" \
> -i v "s4 ( {Cylinder} i3  {Head} i1  {Sector} i4)"

This eliminates sending odd sequences out over mail, etc, and puts
them in one place.

(Note: infinite loops are added in formats with parenthesis that will loop
until data is exhausted)

-S Styles:

Styles are "default", "tcl" and "code".

Using the tcl style the output is Tcl lists:

> rt# ./scsinew -f sd0 -S tcl -C caps -I
> scsi> ndefects 1 1
> 0 {80}
> scsi> defects 84 1 1 84
> 0 {{771 0 18} {771 0 19} {1671 4 87} {1703 3 80} {1704 3 80} {1704 3 81}
{1866 1 95} {1922 0 47} {1932 3 33} {2184 3 8} }
> scsi>

And the verbose TCL style includes any names for the variables:
> rt# !! -v
> ./scsinew -f sd0 -S tcl -C caps -I -v
> scsi> ndefects 1 1
> 0 {{ {Defect list length} 80} }
> scsi> defects 84 1 1 84
> 0 {{{ {Cylinder} 771} { {Head} 0} { {Sector} 18} } {{ {Cylinder} 771}
{ {Head} 0} { {Sector} 19} } {{ {Cylinder} 1671} { {Head} 4} { {Sector} 87} }
{{ {Cylinder} 1703} { {Head} 3} { {Sector} 80} } {{ {Cylinder} 1704}
{ {Head} 3} { {Sector} 80} } {{ {Cylinder} 1704} { {Head} 3} { {Sector} 81} }
{{ {Cylinder} 1866} { {Head} 1} { {Sector} 95} } {{ {Cylinder} 1922}
{ {Head} 0} { {Sector} 47} } {{ {Cylinder} 1932} { {Head} 3} { {Sector} 33} }
{{ {Cylinder} 2184} { {Head} 3} { {Sector} 8} } }
> scsi>

(the line wrap is artificial)

The code style is an incomplete sketch of code generation.
This genarates the in-kernel interface but if this is kept it should
change to a CAM interface as Justin's CAM work progresses.

> ./scsinew -I -C caps -S code
> scsi> ndefects
> errval dev_ndefects(struct scsi_link *sc_link, const int input_arg0,
> const int input_arg1, int *output_arg0)
> {
>    int ret;
>   static const u_char cdb_tmplt[] =
>   {0x37,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x04,0x00,};
>   u_char cdb[sizeof(cdb_tmplt)];
>   u_char data[4];
>   memcpy(cdb, cdb_tmplt, sizeof(cdb));
>   scsi_bits_set(cdb + 2, input_arg0, 1, 3);    /* "plist" get b1 */
>   scsi_bits_set(cdb + 2, input_arg1, 1, 4);    /* "vlist" get b1 */
>   if ( (ret = scsi_scsi_cmd(sc_link,
>      (const struct scsi_generic *)cdb,
>      sizeof(cdb),
>      data,
>      4,
>      dev_retries,
>      2000,
>      NULL,
>      SCSI_DATA_IN)) == 0)
>   {
>      *output_arg0=scsi_2_byte(data + 2);    /* "Defect list length" put i2 */
>
>   }
>   return ret;
>}

The intent is:

1. Use the scsi(8) program, not the scsi(3) library.  Wrap Tk or
perl scripts around the program to make it look good.
2. When you want a library, prototype it using scsi(8) and then
spit out the code using "-S code".

-D Daemon:

The -D switch detaches a scsi daemon.  This permits you to perform
remote maintenance on a small machine with no Tk, etc, loaded up.  The
sample Tk application "zones.wish" will talk to a daemon if given
three arguments.  It needs some more work - it is logging too much
noise to syslog and needs to store away its PID, be visited for
security issues, etc.

Some things to look at:

1. In cmd.c I turned off the noise that echoed arguments back in verbose
mode.  I don't think this is needed.  Look for "if 0"

2. Loops shouldn't be infinite.
