sg3_utils
sg3_utils copied to clipboard
Just curious if the command sg_write_attr is in the works
The READ and WRITE ATTRIBUTE commands are particularly useful for tapes, and for their MAM (cartridge) memory. It should be noted that the READ BUFFER command may be used to read Medium Auxilliary Memory, however the WRITE BUFFER command cannot be used for that purpose. I am not sure if sg_logs or sg_inq can help as they DO provide a lot of useful output, but it would be very nice to have the complement to the READ ATTRIBUTE command added to this library in Github. This would implement the WRITE ATTRIBUTE sg command (sg_write_attr) per the specification documents: the initial draft (SPC-3 revision number 17) spc3r17.pdf, and the final working document (SPC-3 revision number 23) spc3r23.pdf. See http://www.csit-sun.pub.ro/~cpop/Documentatie_SMP/Standarde_magistrale/SCSI/spc3r17.pdf or http://www.13thmonkey.org/documentation/SCSI/spc3r23.pdf for those documents. The IBM LTO SCSI references also briefly discuss these commands - at least as early as Generation 3 (perhaps a tiny bit before - not sure). I am willing to write the code for it, however, I would need a tiny bit of guidance from someone like Doug Gilbert or someone else, who can explain if the attributes are part of a "standard". When I search the MAM memory, I don't find that the tape's cartridge memory information are organized per the tables in sg_read_attr.c in general. Perhaps we need to first write in that format? Can someone explain here? Or she we have a command that allows us to store the offsets into our own (dynamic?) table, that we build up when we find a tape that's not standard. Or are we relying on the firmware in the drive - this is what is confusing me? One last question is, do the LInux generic drivers support this? I assume we do NOT need Vendor-specific drivers. For example, the Host attribute {0x806, "Barcode", RA_FMT_ASCII, 32, 0}, does not always seem to be 32 bytes long, it's more like 8 normally (6 followed by L3 for example). But perhaps this changed as of LTO 4? Anyway, for those tapes that are already written, it would be nice to have a WRITE command that allows writing to an offset in the Medium Access Memory. "A host attribute does not exist in the MAM until a WRITE ATTRIBUTE command creates it." The previous quote answers it partially. Page 156 of the Ultrium SCSI reference for LTO 3 generation section Medium Auxiliary Memory does seem to explain most of what is going on. In the meantime, I'll just use the 8D scsi command which should in theory write an attribute. Any help appreciated while I research this myself.
The barcode field is 32 bytes but any beyond what's actually on the barcode are simple 0x20 characters (ascii space) - Annoyingly many people have assumed 8 characters as a hard limit. please don't. Many of mine are 10 characters for historical reasons (8+2)
The attributes are all standardised. If anyone wants to come up with non-standard ones then they have to use their own attribute number - which is what MPTapes.com have done for MAM entries written by their media eraser and cleaner devices.
When searching for this stuff a couple of years back I found an old linux util which writes the barcode field back to the MAM, in addition to a perl script which did attribute decoding. I commented this up with all the known attributes I could get hold of and their formats (crosschecked between IBM/HP/Quantum documents for lto 4/5/6/7 drives). I'll attach that here as it may be useful.
The ugly bits are mine. Robin Johnson wrote the original small script.
Note that repeated use of sg_read_attr seems to eventually kill the MAM - which is a bit odd given it's not supposed to wrote anything back.
It's also worth noting that sg_read_attr doesn't bring back all these fields, nor does the raw read (Usually 0x3nn are missing at the very least)
#!/usr/bin/perl # This decodes the cartridge memory on LTO tapes # Robin H. Johnson# Usage: # sg_raw -o - -r 1024 -t 60 -v /dev/nst0 8c 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 | ./read_attribute.pl - # OR # sg_read_attr -r {DEVICE} > /tmp/lto use strict; use warnings; use bignum; use bigint; use Number::Format qw(:subs :vars); $THOUSANDS_SEP = '.'; $DECIMAL_POINT = ','; $INT_CURR_SYMBOL = 'DEM'; sub decode_id { my $id = shift; my $s; $s = 'Reserved' if ( ($id >> 8) >= 0x18) ; $s = 'Host (vendor-specific)' if ( ($id >> 8) > 8) > 8) > 8) > 8) > 8) "Remaining Native Capacity in Partition (MiB)", # 8 bytes, Binary # 0x0001 => "Maximum Native Capacity in Partition (MiB)", # 8 bytes, Binary # 0x0002 => "TapeAlert Flags", # 8 bytes, Binary # The tape drive/autoloader flag definition is grouped into the following sections: # Flags 1 to 19: For tape drive write/read management # Flags 20 to 25: For cleaning management # Flags 26 to 39: For tape drive hardware errors # Flags 40 to 49:For tape autoloader errors # # 1 bit per flag (MSB=flag1, LSB=flag64) # Bits specify flags set during last load. # Minimum allowable set: # 3 - Hard error # 4 - Media # 5 - Read Failure # 6 - Write failure # 20 - Clean now # 22 - Cleaning cycle failed (expired cleaning) # 31 - Hardware B (POST failed) # See http://www.t10.org/ftp/t10/document.02/02-142r0.pdf and # http://www-01.ibm.com/support/docview.wss?uid=ssg1S7003556&aid=1 # 0x0003 => "Lifetime Load Count", # 8 bytes, Binary # 0x0004 => "MAM Space Remaining (bytes)", # 8 bytes, Binary # 0x0005 => "Assigning Organization", # 8 bytes, ASCII "LTO-CVE" # 0x0006 => "Formatted Density Code", # 1 bytes, Binary # 0x40 - LTO-1 # 0x42 - LTO-2 # 0x44 - LTO-3 # 0x46 - LTO-4 # 0x58 - LTO-5 # 0x5A - LTO-6 # 0x5C - LTO-7 # 0x ? - LTO-8 # 0x ? - LTO-9 # 0x ? - LTO-10 # (this information used to be maintained by T10.org but no longer is.) # (Future density codes will need need to be empirically determined ) # 0x0007 => "Lifetime Initialization Count (media formatted)", # 1 bytes, Binary # 0 = not initialised # 1 = all other cases # 0x0008 => "Volume Identifier", # 0-32 bytes, ASCII # 0x0009 => "Volume Change Reference", # 4 bytes, Binary # Number of changes to objects on the volume (written objects, overwrites, formatted) # 0x020A => "Tape Device Make/Serial Number at Last Load", # 40 bytes, ASCII # Byte 0 - 7 - T10 vendor ID # Byte 8 - 39 - Device serial number # 0x020B => "Tape Device Make/Serial Number at Load - 1", # 40 bytes, ASCII # Byte 0 - 7 - T10 vendor ID # Byte 8 - 39 - Device serial number # 0x020C => "Tape Device Make/Serial Number at Load - 2", # 40 bytes, ASCII # Byte 0 - 7 - T10 vendor ID # Byte 8 - 39 - Device serial number # 0x020D => "Tape Device Make/Serial Number at Load - 3", # 40 bytes, ASCII # Byte 0 - 7 - T10 vendor ID # Byte 8 - 39 - Device serial number # 0x0220 => "Total Megabytes Written in Medium Life", # 8 bytes, Binary # 0x0221 => "Total Megabytes Read in Medium Life", # 8 bytes, Binary # 0x0222 => "Total Megabytes Written in Current/Last Load", # 8 bytes, Binary # 0x0223 => "Total Megabytes Read in Current/Last Load", # 8 bytes, Binary # 0x0224 => "Logical position of first encrypted block", # 8 bytes, Binary # 0xffff ffff ffff ffff - unencrypted # 0xffff ffff ffff fffe - unknown # Everything else is logical address of first encrypted block # 0x0225 => "Logical position of first unencrypted block after the first encrypted block", # 8 bytes, Binary # 0xffff ffff ffff ffff - unencrypted if 0x0224 = 0xffff ffff ffff fffe # 0xffff ffff ffff ffff - no unencrypted blocks if 0x0224 != (0xffff ffff ffff ffff or 0xffff ffff ffff fffe) # 0xffff ffff ffff fffe - unknown if any unencrypted blocks. # Everything else is logical address of first unencrypted block # 0x0340 => "Medium Usage History", # 90 bytes, Binary # Byte: 0 - 5 - This load - amount of data written (MiB) # 6 - 11 - This load - write retries count # 12 - 17 - This load - amount of data read (MiB) # 18 - 23 - This load - read retries count # 24 - 29 - Last load - amount of data written (MiB) # 30 - 35 - Last load - write retries count # 36 - 41 - Last load - amount of data read (MiB) # 42 - 47 - Last load - read retries count # 48 - 53 - Since last format - amount of data written (MiB) # 54 - 59 - Since last format - write retries count # 60 - 65 - Since last format - amount of data read (MiB) # 66 - 71 - Since last format - read retries count # 72 - 77 - Since last format - load count. # 78 - 83 - Total change partition count (0) # 84 - 89 - Total partition initialise count (0) # 0x0341 => "Partition Usage History", # 60 bytes, Binary # Provides counters for the partition specified by the PARTITION NUMBER field in the CDB. # Data is presented in the same format as the MEDIUM USAGE HISTORY (ID 0340h). # Note that since there is only one partition on the LTO media the PARTITION USAGE HISTORY # will be identical to the MEDIUM USAGE HISTORY # 0x0400 => "Medium Manufacturer", # 8 bytes, ASCII (T10 vendor ID) # 0x0401 => "Medium Serial Number", # 32 bytes, ASCII # 0x0402 => "Medium Length (metres)", # 4 bytes, Binary # 0x0403 => "Medium Width (* 0.1 mm)", # 4 bytes, Binary # 127 (width of tape in 0.1mm units) # 0x0404 => "Assigning Organization", # 8 bytes, ASCII "LTO-CVE" # 0x0405 => "Medium Density Code", # 1 bytes, Binary # Same values as 0x006 Formatted Density Code. # 0x0406 => "Medium Manufacture Date (yyyymmdd)", # 8 bytes, ASCII # 0x0407 => "MAM total capacity (bytes)", # 8 bytes, Binary # 0x0408 => "Medium Type", # 1 bytes, Binary # 0x00 = Data cartridge # 0x01 = Cleaning cartridge # 0x80 = WORM cartridge # 0x0409 => "Medium Type Information (for cleaning media only, max cycles permitted)", # 2 bytes, Binary # For cleaning media only - Maximum number of cycles permitted. # 0x040A => "Numeric Medium Serial Number", # 0x0800 => "Application Vendor", # 8 bytes, ASCII (T10 vendor ID) # 0x0801 => "Application Name", # 32 bytes, ASCII # 0x0802 => "Application Version", # 8 bytes, ASCII # 0x0803 => "User Medium Text Label", # 160 bytes, Text # 0x0804 => "Date & Time Last Written (yyyymmddhhmm)", # 12 bytes, ASCII # 0x0805 => "Text Localization Identifier", # 1 bytes, Binary # 0x00 = No code (ASCII) # 0x01 = ISO/IEC8859-1 (Europe,Latin America) # 0x02 = ISO/IEC8859-2 (Eastern Europe) # 0x03 = ISO/IEC8859-3 (SE Europe/miscellaneous) # 0x04 = ISO/IEC8859-4 (Scandinavia/Baltic) # 0x05 = ISO/IEC8859-5 (Cyrillic) # 0x06 = ISO/IEC8859-6 (Arabic) # 0x07 = ISO/IEC8859-7 (Greek) # 0x08 = ISO/IEC8859-8 (Hebrew) # 0x09 = ISO/IEC8859-9 (Latin5) # 0x0a = ISO/IEC8859-10(Latin6) # 0x80 = ISO/IEC10646 (Unicode) # 0x81 = ISO/IEC10646 -1, Amendment no. 2 (UTF-8) # 0x0806 => "Barcode", # 32 bytes, ASCII # 0x0807 => "Owning Host Textual Name", # 80 bytes, Text # 0x0808 => "Media Pool", # 160 bytes, Text # 0x0809 => "Partition User Text Label", # 16 bytes, ASCII # 0x080A => "Load/Unload at Partition", # 1 bytes, Binary # 0 = Load/unload at start of tape (default) # 1 = Load/unload at partition specified in CDB # 0x080B => "Application Format Version", # 16 bytes, ASCII # 0x080C => "Volume Coherency Information", # 23-n, Binary # Bytes 0 - Attribute length (n) # 1 - n - Volume change reference value # n+1 - n+8 - Volume coherency count # n+9 - n+16 - Volume coherency set identifier # n+17 - n+18 - Application client specific information length (y-(n+18)) # n+19 - y - Application client specific information # 0x0820 => "Medium Globally Unique Identifer (LTFS)", # 36 bytes, Binary # 0x0821 => "Media Pool Globally Unique Identifer (LTFS)", # 36 bytes, Binary # 0x0e0a => "MP Tapes - eraser info", # 54 bytes, Text (Encrypted) # Proprietary data written to LTO-MAM by the MP Tapes cleaning or erasure machines # This contains device details (model/serial number) and date. # 0x1000 => "Unique Cartridge Identity (UCI)", # 28 bytes, Binary # Bytes 0 - 3 - Binary - LTO CM serial (4 bytes) # Bytes 4 - 11 - Binary - Tape pancake ID from manufacturer (8 bytes) # Bytes 12 - 19 - ASCII - Manufacturer name (8 bytes) # Bytes 20 - 23 - Binary - LPOS value at LP1 (4 bytes) # Bytes 24 - 25 - Binary - Cartridge Type (2 bytes) # Bytes 26 - 27 - Reserved - Zero - 2 bytes # 0x1001 => "Alternate Unique Cartridge Identity (Alt-UCI)", # 24 bytes, Binary # Bytes 0 - 3 - Binary - LTO CM serial (4 bytes) # Bytes 4 - 11 - Binary - Tape pancake ID from manufacturer (8 bytes) # Bytes 12 - 21 - Binary - Cartridge serial # (10 bytes) # Bytes 22 - 23 - Binary - Cartridge Type (2 bytes) # 0x1800 => "Automation Vendor", # 8 bytes, ASCII, T10 vendor ID # 0x1800 => "Automation Product ID", # 16 bytes, ASCII # 0x1800 => "Automation Product revision level", # 4 bytes, ASCII # 0x1800 => "Barcode", # 32 bytes, ASCII # ); $s .= ': '; $s .= (defined $ATTRIBUTES{$id}) ? $ATTRIBUTES{$id} : 'UNKNOWN'; return $s; } sub scsi_read_attribute { my $cmd = '8c 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00'; #$cmd =~ s/ +//g; $cmd = pack('H*',$cmd); #my ($result, $sense) = $device->execute($command, $wanted); } sub decode_read_attribute { my $buf = shift; my $offset = 0; my ($size) = unpack('N', $buf); printf("size=%d %x\n", $size, $size); $offset += 4; while($offset > 7; my $format = $tmp & 0x03; $offset += 5; my $val = substr($buf, $offset, $attrlen); printf( "id=0x%04x writable=%s format=%x attrlen=0x%04x=%-5d - %s\n", $id, $ro ? "RO" : "RW", $format, $attrlen, $attrlen, decode_id($id)); if($id == 0x1000 ) { print "\t\t\t\t\t\t\t\t - LTO-CM serial #: ", hex(unpack('H*', substr($val, 0, 4))), "\n", "\t\t\t\t\t\t\t\t - Manf Tape pancake Id: ", unpack('A*', substr($val, 4, 8)), "\n", "\t\t\t\t\t\t\t\t - Manufacturer: ", unpack('A*', substr($val, 12, 8)), "\n", "\t\t\t\t\t\t\t\t - LPOS at LP1: ", hex(unpack('H*', substr($val, 20, 4))), "\n", "\t\t\t\t\t\t\t\t - Cartridge type ", hex(unpack('H*', substr($val, 24, 2))), "\n"; } elsif($id == 0x1001 ) { print "\t\t\t\t\t\t\t\t - LTO-CM serial #: ", hex(unpack('H*', substr($val, 0, 4))), "\n ", "\t\t\t\t\t\t\t\t - Manf Tape pancake Id: ", unpack('A*', substr($val, 4, 8)), "\n ", "\t\t\t\t\t\t\t\t - Cartridge Serial #: ", unpack('A*', substr($val, 12, 10)), "\n", "\t\t\t\t\t\t\t\t - Cartridge type ", hex(unpack('H*', substr($val, 21, 2))), "\n"; } elsif($id == 0x0e0a ) { print "\t\t\t\t\t\t\t\t - mptapes.com - Encrypted data \n"; } elsif($id == 0x0409 ) { print "\t\t\t\t\t\t\t val=0x",unpack('H*', $val)," (", format_number(hex(unpack('H*', $val))),") \n"; if (unpack('H*', $val) == "00") { print "\t\t\t\t\t\t\t\t - (Only applicable to cleaning tapes) \n"; } else { print "\t\t\t\t\t\t\t\t - (Maximum number of cleaning cycles with this cleaning tape) \n"; } } elsif($id == 0x0408 ) { print "\t\t\t\t\t\t\t val=0x",unpack('H*', $val), ", "; if (unpack('H*', $val) == "00") { print "(DATA cartridge) \n"; } elsif (unpack('H*', $val) == "01") { print "(CLEANING cartridge) \n"; } elsif (unpack('H*', $val) == "80") { print "(WORM cartridge) \n"; } else { print "UNKNOWN - PLEASE UPDATE ME \n"; } } elsif($id == 0x0341 ) { print "\t\t\t\t\t\t\t\t - This load - MiB written: ", format_number(hex(unpack('H*', substr($val, 0, 6)))), "\n", "\t\t\t\t\t\t\t\t - This load - write retries: ", format_number(hex(unpack('H*', substr($val, 6, 6)))), " \n", "\t\t\t\t\t\t\t\t - This load - MiB read: ", format_number(hex(unpack('H*', substr($val, 12, 6)))), " \n", "\t\t\t\t\t\t\t\t - This load - read retries: ", format_number(hex(unpack('H*', substr($val, 18, 6)))), " \n", "\t\t\t\t\t\t\t\t - Last load - MiB written: ", format_number(hex(unpack('H*', substr($val, 24, 6)))), " \n", "\t\t\t\t\t\t\t\t - Last load - write retries: ", format_number(hex(unpack('H*', substr($val, 30, 6)))), " \n", "\t\t\t\t\t\t\t\t - Last load - MiB read: ", format_number(hex(unpack('H*', substr($val, 36, 6)))), " \n", "\t\t\t\t\t\t\t\t - Last load - read retries: ", format_number(hex(unpack('H*', substr($val, 42, 6)))), " \n", "\t\t\t\t\t\t\t\t - Since format - MiB written: ", format_number(hex(unpack('H*', substr($val, 48, 6)))), " \n", "\t\t\t\t\t\t\t\t - Since format - write retries: ", format_number(hex(unpack('H*', substr($val, 54, 6)))), " \n", "\t\t\t\t\t\t\t\t - Since format - MiB read: ", format_number(hex(unpack('H*', substr($val, 60, 6)))), " \n", "\t\t\t\t\t\t\t\t - Since format - read retries: ", format_number(hex(unpack('H*', substr($val, 66, 6)))), " \n", "\t\t\t\t\t\t\t\t - Since format - load count: ", format_number(hex(unpack('H*', substr($val, 72, 6)))), " \n", "\t\t\t\t\t\t\t\t - Total change partition count: ", format_number(hex(unpack('H*', substr($val, 78, 6)))), " \n", "\t\t\t\t\t\t\t\t - Total partition ininialise count:", format_number(hex(unpack('H*', substr($val, 84, 6)))), " \n"; } elsif($id == 0x0340 ) { print "\t\t\t\t\t\t\t\t - This load - MiB written: ", format_number(hex(unpack('H*', substr($val, 0, 6)))), "\n", "\t\t\t\t\t\t\t\t - This load - write retries: ", format_number(hex(unpack('H*', substr($val, 6, 6)))), " \n", "\t\t\t\t\t\t\t\t - This load - MiB read: ", format_number(hex(unpack('H*', substr($val, 12, 6)))), " \n", "\t\t\t\t\t\t\t\t - This load - read retries: ", format_number(hex(unpack('H*', substr($val, 18, 6)))), " \n", "\t\t\t\t\t\t\t\t - Last load - MiB written: ", format_number(hex(unpack('H*', substr($val, 24, 6)))), " \n", "\t\t\t\t\t\t\t\t - Last load - write retries: ", format_number(hex(unpack('H*', substr($val, 30, 6)))), " \n", "\t\t\t\t\t\t\t\t - Last load - MiB read: ", format_number(hex(unpack('H*', substr($val, 36, 6)))), " \n", "\t\t\t\t\t\t\t\t - Last load - read retries: ", format_number(hex(unpack('H*', substr($val, 42, 6)))), " \n", "\t\t\t\t\t\t\t\t - Since format - MiB written: ", format_number(hex(unpack('H*', substr($val, 48, 6)))), " \n", "\t\t\t\t\t\t\t\t - Since format - write retries: ", format_number(hex(unpack('H*', substr($val, 54, 6)))), " \n", "\t\t\t\t\t\t\t\t - Since format - MiB read: ", format_number(hex(unpack('H*', substr($val, 60, 6)))), " \n", "\t\t\t\t\t\t\t\t - Since format - read retries: ", format_number(hex(unpack('H*', substr($val, 66, 6)))), " \n", "\t\t\t\t\t\t\t\t - Since format - load count: ", format_number(hex(unpack('H*', substr($val, 72, 6)))), " \n", "\t\t\t\t\t\t\t\t - Total change partition count: ", format_number(hex(unpack('H*', substr($val, 78, 6)))), " \n", "\t\t\t\t\t\t\t\t - Total partition ininialise count:", format_number(hex(unpack('H*', substr($val, 84, 6)))), " \n"; } elsif($id == 0x0225 ) { print "\t\t\t\t\t\t\t val=0x", unpack('H*', $val), " "; if (unpack('H*', $val) =~ "ffffffffffffffff") { print " (Not applicable or no unencrypted blocks) \n"; } elsif (unpack('H*', $val) =~ "fffffffffffffffe") { print " (Start unencrypted block unknown) \n"; } else { print "\n"; } } elsif($id == 0x0224 ) { print "\t\t\t\t\t\t\t val=0x", unpack('H*', $val), " "; if (unpack('H*', $val) =~ "ffffffffffffffff") { print " (NOT ENCRYPTED) \n"; } elsif (unpack('H*', $val) =~ "fffffffffffffffe") { print " (Starting encypted block unknown) \n"; } else { print "\n"; } } elsif($id == 0x0006 ) { print "\t\t\t\t\t\t\t val=0x",unpack('H*', $val), ", "; if (unpack('H*', $val) == "40") { print "(LTO-1) \n"; } elsif (unpack('H*', $val) == "42") { print "(LTO-2) \n"; } elsif (unpack('H*', $val) == "44") { print "(LTO-3) \n"; } elsif (unpack('H*', $val) == "46") { print "(LTO-4) \n"; } elsif (unpack('H*', $val) == "58") { print "(LTO-5) \n"; } elsif (unpack('H*', $val) == "5A") { print "(LTO-6) \n"; } elsif (unpack('H*', $val) == "5C") { print "(LTO-7) \n"; } else { print "UNKNOWN - PLEASE UPDATE ME \n"; } } elsif($id == 0x0002 ) { print "\t\t\t\t\t\t\t val=0x",unpack('H*', $val)," (",unpack('b*', $val),") \n"; } elsif($format == 0) { print "\t\t\t\t\t\t\t val=0x",unpack('H*', $val)," (",format_number(hex(unpack('H*', $val))),") \n"; } elsif($format == 1 || $format == 2) { print "\t\t\t\t\t\t\t\t - ",unpack('A*', $val), "\n"; } $offset += $attrlen; } } sub read_file { my $filename = shift; open FILE, '
It's worth having this kicking around as the alert codes are the same on the MAM as here.
Tape alert page (ssc-3) [0x2e] 1 Read warning 2 Write warning 3 Hard error 4 Media 5 Read failure 6 Write failure 7 Media life 8 Not data grade 9 Write protect 10 No removal 11 Cleaning media 12 Unsupported format 13 Recoverable mechanical cartridge failure 14 Unrecoverable mechanical cartridge failure 15 Memory chip in cartridge failure 16 Forced eject 17 Read only format 18 Tape directory corrupted on load 19 Nearing media life 20 Cleaning required 21 Cleaning requested 22 Expired cleaning media 23 Invalid cleaning tape 24 Retension requested 25 Dual port interface error 26 Cooling fan failing 27 Power supply failure 28 Power consumption 29 Drive maintenance 30 Hardware A 31 Hardware B 32 Interface 33 Eject media 34 Microcode update fail 35 Drive humidity 36 Drive temperature 37 Drive voltage 38 Predictive failure 39 Diagnostics required 40 Obsolete (28h) 41 Obsolete (29h) 42 Obsolete (2Ah) 43 Obsolete (2Bh) 44 Obsolete (2Ch) 45 Obsolete (2Dh) 46 Obsolete (2Eh) 47 Reserved (2Fh) 48 Reserved (30h) 49 Reserved (31h) 50 Lost statistics 51 Tape directory invalid at unload 52 Tape system area write failure 53 Tape system area read failure 54 No start of data 55 Loading failure 56 Unrecoverable unload failure 57 Automation interface failure 58 Firmware failure 59 WORM medium - integrity check failed 60 WORM medium - overwrite attempted 61 Reserved parameter code 0x3d, flag 62 Reserved parameter code 0x3e, flag 63 Reserved parameter code 0x3f, flag 64 Reserved parameter code 0x40, flag
Hi, thanks for the script and the info. I can build and run all of these commands now. My problem had been driver/scsi-card related. A certain driver simply could not pass-through or issue 16-byte commands. I will some day fix that driver by recompiling it but that may have to wait awhile. I simply got a different scsi card and driver and it all works.
Hi,
I keep getting:
round() overflow. Try smaller precision or use Math::BigFloat at read_attribute.pl line 339
Lines 339-344 it's referring to below:
if($id == 0x1000 ) { print "\t\t\t\t\t\t\t\t - LTO-CM serial #: ", hex(unpack('H*', substr($val, 0, 4))), "\n", "\t\t\t\t\t\t\t\t - Manf Tape pancake Id: ", unpack('A*', substr($val, 4, 8)), "\n", "\t\t\t\t\t\t\t\t - Manufacturer: ", unpack('A*', substr($val, 12, 8)), "\n", "\t\t\t\t\t\t\t\t - LPOS at LP1: ", hex(unpack('H*', substr($val, 20, 4))), "\n", "\t\t\t\t\t\t\t\t - Cartridge type ", hex(unpack('H*', substr($val, 24, 2))), "\n";
Has it got something to do with an old perl version (v5.14.2 in my case) or something else?
Thanks, Adam
Hi,
See PR #87.
Boris
PR got merged.