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.