diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2014-09-30 17:01:23 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2014-09-30 17:01:23 +0000 |
commit | d499582946b7681d941abb71d8f87dc4dfa1a1b1 (patch) | |
tree | 42f5d6dba4e80561ef3fd655d83f1c141ec7790b | |
parent | 50b76f8e999dbc4328e3978b645d057721faa870 (diff) | |
download | sg3_utils-d499582946b7681d941abb71d8f87dc4dfa1a1b1.tar.gz |
sg_ses_microcode: add --non optio to bypass RDR calls
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@611 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | doc/sg3_utils.8 | 6 | ||||
-rw-r--r-- | doc/sg_ses.8 | 30 | ||||
-rw-r--r-- | doc/sg_ses_microcode.8 | 30 | ||||
-rw-r--r-- | doc/sg_write_buffer.8 | 4 | ||||
-rw-r--r-- | doc/sg_write_verify.8 | 12 | ||||
-rw-r--r-- | src/sg_ses.c | 12 | ||||
-rw-r--r-- | src/sg_ses_microcode.c | 45 |
8 files changed, 88 insertions, 53 deletions
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and some description at the top of its ".c" file. All utilities in the main directory have their own "man" pages. There is also a sg3_utils man page. -Changelog for sg3_utils-1.40 [20140929] [svn: r610] +Changelog for sg3_utils-1.40 [20140930] [svn: r611] - sg_write_verify: new utility for WRITE AND VERIFY - sg_ses_microcode: new utility - sg_senddiag: add --maxlen= option diff --git a/doc/sg3_utils.8 b/doc/sg3_utils.8 index f3edb750..bbe3483c 100644 --- a/doc/sg3_utils.8 +++ b/doc/sg3_utils.8 @@ -417,6 +417,12 @@ in the C programming language. The second hexadecimal representation is a trailing "h" or "H" as found in (storage) standards. When hex numbers are given, multipliers cannot be used. For example the decimal value "256" can be given as "0x100" or "100h". +.SH MICROCODE AND FIRMWARE +There are two standardized methods for downloading microcode (i.e. device +firmware) to a SCSI device. The more general way is with the SCSI WRITE +BUFFER command, see the sg_write_buffer utility. SCSI enclosures have +their own method based on the Download microcode control/status diagnostic +page, see the sg_ses_microcode utility. .SH SCRIPTS, EXAMPLES and UTILS There are several bash shell scripts in the 'scripts' subdirectory that invoke compiled utilities (e.g. sg_readcap). Several of the scripts start diff --git a/doc/sg_ses.8 b/doc/sg_ses.8 index a8bdc4bf..4dfe5087 100644 --- a/doc/sg_ses.8 +++ b/doc/sg_ses.8 @@ -89,7 +89,7 @@ detected. .TP \fB\-d\fR, \fB\-\-data\fR=@\fIFN\fR reads one or more data strings from the file called \fIFN\fR, limit 2048 -bytes. Othewise this option is the same as the previous item that reads +bytes. Otherwise this option is the same as the previous item that reads from stdin. .TP \fB\-D\fR, \fB\-\-descriptor\fR=\fIDN\fR @@ -98,15 +98,15 @@ Descriptor page. This is a medium level indexing alternative to the low level \fI\-\-index=\fR options. If the descriptor name contains a space then \fIDN\fR needs to be surrounded by quotes (single or double) or the space escaped (e.g. preceded by a backslash). See the DESCRIPTOR NAME, DEVICE SLOT -NAME AND SAS ADDRESS section below. +NUMBER AND SAS ADDRESS section below. .TP -\fB\-x\fR, \fB\-\-dev\-slot\-num\fR=\fISN\fR +\fB\-x\fR, \fB\-\-dev\-slot\-num\fR=\fISN\fR, \fB\-\-dsn\fR=\fISN\fR where \fISN\fR is a device slot number found in the Additional Element Status page. Only entries for FCP and SAS devices (with EIP=1) have device slot -numbers. \fISN\fR must be a number in the range 0 to 255 (inclusive). This is -a medium level indexing alternative to the low level \fI\-\-index=\fR -options. See the DESCRIPTOR NAME, DEVICE SLOT NAME AND SAS ADDRESS section -below. +numbers. \fISN\fR must be a number in the range 0 to 255 (inclusive). 255 is +used to indicate there is no corresponding device slot. This is a medium level +indexing alternative to the low level \fI\-\-index=\fR options. See the +DESCRIPTOR NAME, DEVICE SLOT NUMBER AND SAS ADDRESS section below. .TP \fB\-E\fR, \fB\-\-eiioe\fR=\fIA_F\fR \fIA_F\fR is either the string 'auto' or 'force'. There was some fuzziness @@ -187,10 +187,10 @@ group elements from the Element Descriptor, Enclosure Status and Additional Element Status pages. If this option is given twice then elements from the Threshold In page are also grouped. The order is dictated by the Configuration page. All elements are output unless one of the indexing options is given, -in which case only the matching element and its associateds are output. The -\fI\-\-filter\fR option can be added to reduce the amount of output generated -by this option. See the INDEXES and DESCRIPTOR NAME, DEVICE SLOT NAME AND SAS -ADDRESS sections below. +in which case only the matching element and its associated fields are output. +The \fI\-\-filter\fR option can be added to reduce the amount of output +generated by this option. See the INDEXES and DESCRIPTOR NAME, DEVICE SLOT +NUMBER AND SAS ADDRESS sections below. .TP \fB\-l\fR, \fB\-\-list\fR This option is equivalent to \fI\-\-enumerate\fR. See that option. @@ -239,7 +239,7 @@ manufactured target port identifier is different from a SATA disk's WWN. \fISA\fR is a hex number that is up to 8 digits long. It may have a leading '0x' or '0X' or a trailing 'h' or 'H'. This option is a medium level indexing alternative to the low level \fI\-\-index=\fR options. -See the DESCRIPTOR NAME, DEVICE SLOT NAME AND SAS ADDRESS section below. +See the DESCRIPTOR NAME, DEVICE SLOT NUMBER AND SAS ADDRESS section below. .TP \fB\-S\fR, \fB\-\-set\fR=\fISTR\fR Used to set an element field in the Enclosure Control or Threshold Out page. @@ -271,7 +271,7 @@ Addressing a specific element (overall or individual) within a page is complicated. This section describes low level indexing (i.e. choosing a single element (or a group of related elements) from a large number of elements). If available, the medium level indexing described in the -following section (DESCRIPTOR NAME, DEVICE SLOT NAME AND SAS ADDRESS) +following section (DESCRIPTOR NAME, DEVICE SLOT NUMBER AND SAS ADDRESS) might be simpler to use. .PP The Configuration page is key to low level indexing: it contains a list @@ -329,7 +329,7 @@ output (e.g. only showing the element associated with the second 12 volt power supply). They may also be used together with with the \fI\-\-clear=STR\fR, \fI\-\-get=STR\fR and \fI\-\-set=STR\fR options which are described in the STR section below. -.SH DESCRIPTOR NAME, DEVICE SLOT NAME AND SAS ADDRESS +.SH DESCRIPTOR NAME, DEVICE SLOT NUMBER AND SAS ADDRESS The three options: \fI\-\-descriptor=DN\fR, \fI\-\-dev\-slot\-num=SN\fR and \fI\-\-sas\-addr=SA\fR allow medium level indexing, as an alternative to the low level \fI\-\-index=\fR options. Only one of the three options @@ -368,7 +368,7 @@ is usually in the range 0 to 3, the <start_bit> must be in the range 0 to number of bits are read in the left to right sense of the element tables shown in the various SES draft documents. For example the 8 bits of byte 2 would be represented as 2:7:8 with the most significant bit being -2:7 and the least sugnificant bit being 2:0 . +2:7 and the least significant bit being 2:0 . .PP The <value> is optional but is ignored if provided to \fI\-\-get=STR\fR. For \fI\-\-set=STR\fR the default <value> is 1 while for \fI\-\-clear=STR\fR diff --git a/doc/sg_ses_microcode.8 b/doc/sg_ses_microcode.8 index b7ead358..f3a7ff7b 100644 --- a/doc/sg_ses_microcode.8 +++ b/doc/sg_ses_microcode.8 @@ -4,16 +4,16 @@ sg_ses_microcode \- send microcode to a SCSI enclosure .SH SYNOPSIS .B sg_ses_microcode [\fI\-\-bpw=CS\fR] [\fI\-\-help\fR] [\fI\-\-id=ID\fR] [\fI\-\-in=FILE\fR] -[\fI\-\-length=LEN\fR] [\fI\-\-mode=MO\fR] [\fI\-\-offset=OFF\fR] -[\fI\-\-skip=SKIP\fR] [\fI\-\-subenc=MS\fR] [\fI\-\-tlength=TLEN\fR] -[\fI\-\-verbose\fR] [\fI\-\-version\fR] \fIDEVICE\fR +[\fI\-\-length=LEN\fR] [\fI\-\-mode=MO\fR] [\fI\-\-non\fR] +[\fI\-\-offset=OFF\fR] [\fI\-\-skip=SKIP\fR] [\fI\-\-subenc=MS\fR] +[\fI\-\-tlength=TLEN\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR] \fIDEVICE\fR .SH DESCRIPTION .\" Add any additional description here .PP -This utility attempts to download microcode to an enclosure (or an -associated sub\-enclosure) associated with the \fIDEVICE\fR. The -process for doing this is defined in the SCSI Enclosure Services (SES) -standards and drafts maintained by the T10 committee. +This utility attempts to download microcode to an enclosure (or one of its +sub\-enclosures) associated with the \fIDEVICE\fR. The process for doing +this is defined in the SCSI Enclosure Services (SES) standards and drafts +maintained by the T10 committee. .PP The process is to send one or more sequences containing a SCSI SEND DIAGNOSTIC command followed by a RECEIVE DIAGNOSTIC RESULTS command. The @@ -22,8 +22,8 @@ the latter fetches a Download microcode status dpage which can be viewed as a report on the former command. .PP The default action (i.e. when the \fI\-\-mode=MO\fR option is not given) -is fetch the Download microcode status dpage and print it to the console. -This does not need any additional data so the \fI\-\-in=FILE\fR option +is to fetch the Download microcode status dpage and decode it. This does +not require the microcode (firmware) itself so the \fI\-\-in=FILE\fR option is not required. .PP The most recent reference for this utility is the draft SCSI Enclosure @@ -32,7 +32,7 @@ Existing standards for SES and SES\-2 are ANSI INCITS 305\-1998 and ANSI INCITS 448\-2008 respectively. .PP Most other support for SES in this package (apart from downloading -microcode) can be found in the sg_ses package. Another way of downloading +microcode) can be found in the sg_ses utility. Another way of downloading firmware to a SCSI device is with the WRITE BUFFER command defined in SPC\-4, see the sg_write_buffer utility. .SH OPTIONS @@ -43,13 +43,13 @@ where \fICS\fR is the chunk size in bytes and should be a multiple of 4. This will be the maximum number of bytes sent per SEND DIAGNOSTIC command. So if \fICS\fR is less than the effective length of the microcode then multiple SEND DIAGNOSTIC commands are sent, each taking the next chunk -from the read data and inceasing the buffer offset field in the Download +from the read data and increasing the buffer offset field in the Download microcode control dpage by the appropriate amount. The default is a chunk size of 0 which is interpreted as a very large number hence only one SEND DIAGNOSTIC command will be sent. .br The number in \fICS\fR can optionally be followed by ",act" or ",activate". -In this case after the microcode has been successfuly sent to the +In this case after the microcode has been successfully sent to the \fIDEVICE\fR, an additional Download microcode control dpage with its mode set to "Activate deferred microcode" [0xf] is sent. .TP @@ -82,6 +82,12 @@ an abbreviation can be given. See the MODES section below. To list the available mode abbreviations at run time give an invalid one (e.g. '\-\-mode=xxx') or use the '\-h' option. .TP +\fB\-N\fR, \fB\-\-non\fR +allow for non\-standard implementations that reset their Download microcode +engine after a RECEIVE DIAGNOSTIC RESULTS command with the Download microcode +status dpage is sent. When this option is given sending that command and +dpage combination is avoided unless an error has already occurred. +.TP \fB\-o\fR, \fB\-\-offset\fR=\fIOFF\fR this option sets the BUFFER OFFSET field in the Download microcode control dpage. \fIOFF\fR is a value between 0 (default) and 2**32\-1 . It is a diff --git a/doc/sg_write_buffer.8 b/doc/sg_write_buffer.8 index 66b9e23b..1dfc9be6 100644 --- a/doc/sg_write_buffer.8 +++ b/doc/sg_write_buffer.8 @@ -25,7 +25,7 @@ Arguments to long options are mandatory for short options as well. where \fICS\fR is the chunk size in bytes. This will be the maximum number of bytes sent per WRITE BUFFER command. So if \fICS\fR is less than the effective length then multiple WRITE BUFFER commands are sent, each taking -the next chunk from the read data and inceasing the buffer offset field +the next chunk from the read data and increasing the buffer offset field in the WRITE BUFFER command by the appropriate amount. The default is a chunk size of 0 which is interpreted as a very large number hence only one WRITE BUFFER command will be sent. This option should only be used with @@ -157,7 +157,7 @@ driver) and various setting in sysfs in the Linux lk 2.6/3 series (e.g. /sys/block/sda/queue/max_sectors_kb). Devices (i.e. logical units) also typically have limits on the maximum amount of data they can handle in one command. These two limitations suggest that modes -containing the word "offset" togther with the \fI\-\-bpw=CS\fR option +containing the word "offset" together with the \fI\-\-bpw=CS\fR option are required as firmware files get larger and larger. And \fICS\fR can be quite small, for example 4096 bytes, resulting in many WRITE BUFFER commands being sent. diff --git a/doc/sg_write_verify.8 b/doc/sg_write_verify.8 index 5d6f27dd..195fa1ae 100644 --- a/doc/sg_write_verify.8 +++ b/doc/sg_write_verify.8 @@ -25,7 +25,7 @@ buffer. .PP The relationship between the number of logical blocks to be written (i.e. \fINUM\fR) and the length (in bytes) of the data\-out buffer (i.e. -\fIILEN\fR) may be simply found by multiplying the former by the logica +\fIILEN\fR) may be simply found by multiplying the former by the logical block size. However if the \fIDEVICE\fR has protection information (PI) then it becomes a bit more complicated. Hence the calculation is left to the user with the default \fIILEN\fR, in the absence of the \fIIF\fR file, @@ -48,7 +48,7 @@ where \fIBC\fR is the value to place in the command's BYTCHK field. Values between 0 and 3 (inclusive) are accepted. The default is value is 0 which implies only a write to the medium then a verify operation are performed. The only other value T10 defines currently is 1 which does performs an additional -comparision between the data\-out buffer that was used by the write operation +comparison between the data\-out buffer that was used by the write operation and the contents of the logical blocks read back from the medium. .TP \fB\-d\fR, \fB\-\-dpo\fR @@ -109,7 +109,7 @@ set the WRPROTECT field in the cdb to \fIWP\fR. The default value is 0 which implies no protection information is sent (along with the user data) in the data\-out buffer. .SH REPEAT -For data sizes around a megabyte and larger, it may be appropraite to send +For data sizes around a megabyte and larger, it may be appropriate to send multiple SCSI WRITE AND VERIFY commands due to operating system limitations (e.g. pass\-through SCSI interfaces often limit the amount of data that can be passed with a SCSI command). With this utility the @@ -165,7 +165,7 @@ data\-out comparison to the read back data: .PP The ddpt command can do copies between SCSI devices using READ and WRITE commands. However, currently it has no facility to promote those WRITES -to WRITE AND VERIFY coomands. Using a pipe, that could be done like this: +to WRITE AND VERIFY commands. Using a pipe, that could be done like this: .PP # ddpt if=/dev/sg2 bs=512 bpt=8 count=11 of=- | .br @@ -173,10 +173,10 @@ sg_write_verify \-\-in=\- \-l 0x567 \-n 8 \-\-ilen=4096 \-\-repeat /dev/sg4 .PP Both ddpt and sg_write_verify are configured for segments of 8 512 byte logical blocks. Since 11 logical blocks are read then first 8 logical blocks -are copied followed by a copy of the remaing 3 blocks. Since it is assumed +are copied followed by a copy of the remaining 3 blocks. Since it is assumed that there is no protection information then the data\-in and data\-out buffers will be 4096 bytes each. For sg_write_verify this needs to be stated -explicity with the \-\-ilen=4096 option. +explicitly with the \-\-ilen=4096 option. .SH AUTHORS Bruno Goncalves and Douglas Gilbert. .SH "REPORTING BUGS" diff --git a/src/sg_ses.c b/src/sg_ses.c index cf03bbab..9ff360d3 100644 --- a/src/sg_ses.c +++ b/src/sg_ses.c @@ -29,7 +29,7 @@ * commands tailored for SES (enclosure) devices. */ -static const char * version_str = "1.94 20140929"; /* ses3r06 */ +static const char * version_str = "1.95 20140930"; /* ses3r06 */ #define MX_ALLOC_LEN ((64 * 1024) - 4) /* max allowable for big enclosures */ #define MX_ELEM_HDR 1024 @@ -483,6 +483,7 @@ static struct option long_options[] = { {"data", required_argument, 0, 'd'}, {"descriptor", required_argument, 0, 'D'}, {"dev-slot-num", required_argument, 0, 'x'}, + {"dsn", required_argument, 0, 'x'}, {"eiioe", required_argument, 0, 'E'}, {"enumerate", no_argument, 0, 'e'}, {"filter", no_argument, 0, 'f'}, @@ -553,9 +554,9 @@ usage(int help_num) " [--version] [--warn] DEVICE\n" " where the main options are:\n" " --clear=STR|-C STR clear field by acronym or position\n" - " --descriptor=DN|-D DN descriptor name, indexing method\n" - " --dev-slot-num=SN|-x SN device slot number, indexing " - "method\n" + " --descriptor=DN|-D DN descriptor name (for indexing)\n" + " --dev-slot-num=SN|--dsn=SN|-x SN device slot number " + "(for indexing)\n" " --eiioe=A_F|-E A_F where A_F is either 'auto' or 'force'." "'force'\n" " acts as if EIIOE is set, 'auto' tries " @@ -592,8 +593,7 @@ usage(int help_num) "or number)\n" " (def: 'ssp' [0x0] (supported diagnostic " "pages))\n" - " --sas-addr=SA|-A SA SAS address in hex, indexing " - "method\n" + " --sas-addr=SA|-A SA SAS address in hex (for indexing)\n" " --set=STR|-S STR set value of field by acronym or " "position\n\n" "Fetches status or sends control data to a SCSI enclosure. Use " diff --git a/src/sg_ses_microcode.c b/src/sg_ses_microcode.c index aa9d196f..54d45062 100644 --- a/src/sg_ses_microcode.c +++ b/src/sg_ses_microcode.c @@ -36,7 +36,7 @@ * RESULTS commands in order to send microcode to the given SES device. */ -static const char * version_str = "1.00 20140829"; /* ses3r06 */ +static const char * version_str = "1.00 20140830"; /* ses3r06 */ #define ME "sg_ses_microcode: " #define MAX_XFER_LEN (128 * 1024 * 1024) @@ -53,6 +53,7 @@ struct opts_t { int mc_len; int mc_len_given; int mc_mode; + int mc_non; int mc_offset; int mc_skip; int mc_subenc; @@ -67,6 +68,7 @@ static struct option long_options[] = { {"in", required_argument, 0, 'I'}, {"length", required_argument, 0, 'l'}, {"mode", required_argument, 0, 'm'}, + {"non", no_argument, 0, 'N'}, {"offset", required_argument, 0, 'o'}, {"skip", required_argument, 0, 's'}, {"subenc", required_argument, 0, 'S'}, @@ -103,10 +105,12 @@ usage() pr2serr("Usage: " "sg_ses_microcode [--bpw=CS] [--help] [--id=ID] [--in=FILE]\n" " [--length=LEN] [--mode=MO] " - "[--offset=OFF]\n" - " [--skip=SKIP] [--subenc=SEID] " - "[--tlength=TLEN]\n" - " [--verbose] [--version] DEVICE\n" + "[--non]\n" + " [--offset=OFF] [--skip=SKIP] " + "[--subenc=SEID]\n" + " [--tlength=TLEN] [--verbose] " + "[--version]\n" + " DEVICE\n" " where:\n" " --bpw=CS|-b CS CS is chunk size: bytes per send " "diagnostic\n" @@ -123,6 +127,10 @@ usage() " --mode=MO|-m MO download microcode mode, MO is " "number or\n" " acronym (def: 0 -> 'dmc_status')\n" + " --non|-N non-standard: bypass all receive " + "diagnostic\n" + " results commands except after check " + "condition\n" " --offset=OFF|-o OFF buffer offset (unit: bytes, def: " "0);\n" " ignored if --bpw=CS given\n" @@ -328,12 +336,19 @@ send_then_receive(int sg_fd, uint32_t gen_code, int off_off, 0 /* devofl */, 0 /* unitofl */, 1 /* long_duration */, wp->doutp, do_len, 1 /* noisy */, op->verbose); - if (res) + if (op->mc_non) { + /* If non-standard, only call RDR after failed SD */ + if (0 == res) + return 0; + /* If RDR error after SD error, prefer reporting SD error */ + ret = res; + } else if (res) return res; + res = sg_ll_receive_diag(sg_fd, 1 /* pcv */, DPC_DOWNLOAD_MICROCODE, dip, DEF_DI_LEN, 1, op->verbose); if (res) - return res; + return ret ? ret : res; rsp_len = sg_get_unaligned_be16(dip + 2) + 4; if (rsp_len > DEF_DI_LEN) { pr2serr("<<< warning response buffer too small [%d but need " @@ -342,7 +357,7 @@ send_then_receive(int sg_fd, uint32_t gen_code, int off_off, } if (rsp_len < 8) { pr2serr("Download microcode status dpage too short\n"); - return SG_LIB_CAT_OTHER; + return ret ? ret : SG_LIB_CAT_OTHER; } rec_gen_code = sg_get_unaligned_be32(dip + 4); if (rec_gen_code != gen_code) @@ -361,7 +376,7 @@ send_then_receive(int sg_fd, uint32_t gen_code, int off_off, pr2serr("mc offset=%d: status: %s [0x%x, additional=0x%x]\n", off_off, cp, mc_status, ucp[3]); if (mc_status >= 0x80) - ret = SG_LIB_CAT_OTHER; + ret = ret ? ret : SG_LIB_CAT_OTHER; } } return ret; @@ -394,7 +409,7 @@ main(int argc, char * argv[]) while (1) { int option_index = 0; - c = getopt_long(argc, argv, "b:hi:I:l:m:o:s:S:t:vV", long_options, + c = getopt_long(argc, argv, "b:hi:I:l:m:No:s:S:t:vV", long_options, &option_index); if (c == -1) break; @@ -457,6 +472,9 @@ main(int argc, char * argv[]) } } break; + case 'N': + ++op->mc_non; + break; case 'o': op->mc_offset = sg_get_num(optarg); if (op->mc_offset < 0) { @@ -652,6 +670,11 @@ main(int argc, char * argv[]) } if (op->mc_tlen < op->mc_len) op->mc_tlen = op->mc_len; + if (op->mc_non && (MODE_DNLD_STATUS == op->mc_mode)) { + pr2serr("Do nothing because '--non' given so fetching the Download " + "microcode status\ndpage might be dangerous\n"); + goto fini; + } if (NULL == (dip = (unsigned char *)malloc(DEF_DI_LEN))) { pr2serr(ME "out of memory (data-in buffer)\n"); @@ -659,7 +682,7 @@ main(int argc, char * argv[]) goto fini; } memset(dip, 0, DEF_DI_LEN); - /* Fetch Download microde status dpage for generation code ++ */ + /* Fetch Download microcode status dpage for generation code ++ */ res = sg_ll_receive_diag(sg_fd, 1 /* pcv */, DPC_DOWNLOAD_MICROCODE, dip, DEF_DI_LEN, 1, op->verbose); if (0 == res) { |