static void usage() { pr2serr("Usage: sg_referrals [--help] [--hex] [--lba=LBA] " "[--maxlen=LEN]\n" " [--one-segment] [--raw] [--readonly] " "[--verbose]\n" " [--version] DEVICE\n" " where:\n" " --help|-h print out usage message\n" " --hex|-H output in hexadecimal\n" " --lba=LBA|-l LBA starting LBA (logical block address) " "(def: 0)\n" " --maxlen=LEN|-m LEN max response length (allocation " "length in cdb)\n" " (def: 0 -> %d bytes)\n", DEF_REFER_BUFF_LEN ); pr2serr(" --one-segment|-s return information about the specified " "segment only\n" " --raw|-r output in binary\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" "Performs a SCSI REPORT REFERRALS command (SBC-3)\n" ); }
static void write2wfn(FILE * fp, struct opts_t * op) { int k, n; size_t s; char b[128]; if (op->do_hex) { for (k = 0, n = 0; k < op->sense_len; ++k) { n += sprintf(b + n, "0x%02x,", op->sense[k]); if (15 == (k % 16)) { b[n] = '\n'; s = fwrite(b, 1, n + 1, fp); if ((int)s != (n + 1)) pr2serr("only able to write %d of %d bytes to %s\n", (int)s, n + 1, op->wfname); n = 0; } } if (n > 0) { b[n] = '\n'; s = fwrite(b, 1, n + 1, fp); if ((int)s != (n + 1)) pr2serr("only able to write %d of %d bytes to %s\n", (int)s, n + 1, op->wfname); } } else { s = fwrite(op->sense, 1, op->sense_len, fp); if ((int)s != op->sense_len) pr2serr("only able to write %d of %d bytes to %s\n", (int)s, op->sense_len, op->wfname); } }
static void calc_duration_throughput(int contin) { struct timeval end_tm, res_tm; double a, b; if (start_tm_valid && (start_tm.tv_sec || start_tm.tv_usec)) { gettimeofday(&end_tm, NULL); res_tm.tv_sec = end_tm.tv_sec - start_tm.tv_sec; res_tm.tv_usec = end_tm.tv_usec - start_tm.tv_usec; if (res_tm.tv_usec < 0) { --res_tm.tv_sec; res_tm.tv_usec += 1000000; } a = res_tm.tv_sec; a += (0.000001 * res_tm.tv_usec); b = (double)blk_sz * (req_count - dd_count); pr2serr("time to transfer data%s: %d.%06d secs", (contin ? " so far" : ""), (int)res_tm.tv_sec, (int)res_tm.tv_usec); if ((a > 0.00001) && (b > 511)) pr2serr(" at %.2f MB/sec\n", b / (a * 1000000.0)); else pr2serr("\n"); } }
/* Invokes a SCSI READ BUFFER(10) command (spc5r02). Return of 0 -> success, * various SG_LIB_CAT_* positive values or -1 -> other errors */ static int sg_ll_read_buffer_10(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id, uint32_t rb_offset, void * resp, int mx_resp_len, int * residp, bool noisy, int verbose) { int k, ret, res, sense_cat; uint8_t rb10_cb[SG_READ_BUFFER_10_CMDLEN] = {SG_READ_BUFFER_10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; rb10_cb[1] = (uint8_t)(rb_mode & 0x1f); if (rb_mode_sp) rb10_cb[1] |= (uint8_t)((rb_mode_sp & 0x7) << 5); rb10_cb[2] = (uint8_t)rb_id; sg_put_unaligned_be24(rb_offset, rb10_cb + 3); sg_put_unaligned_be24(mx_resp_len, rb10_cb + 6); if (verbose) { pr2serr(" Read buffer(10) cdb: "); for (k = 0; k < SG_READ_BUFFER_10_CMDLEN; ++k) pr2serr("%02x ", rb10_cb[k]); pr2serr("\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { pr2serr("Read buffer(10): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rb10_cb, sizeof(rb10_cb)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (uint8_t *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "Read buffer(10)", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ret = sg_convert_errno(get_scsi_pt_os_err(ptvp)); else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = sense_cat; break; } } else { if ((verbose > 2) && (ret > 0)) { pr2serr(" Read buffer(10): response%s\n", (ret > 256 ? ", first 256 bytes" : "")); hex2stderr((const uint8_t *)resp, (ret > 256 ? 256 : ret), -1); } ret = 0; } if (residp) *residp = get_scsi_pt_resid(ptvp); destruct_scsi_pt_obj(ptvp); return ret; }
static void usage() { pr2serr("Usage: " "sg_bg_ctl [--ctl=CTL] [--help] [--time=TN] [--verbose] " "[--version]\n" " DEVICE\n"); pr2serr(" where:\n" " --ctl=CTL|-c CTL CTL is background operation control " "value\n" " default: 0 -> don't change background " "operations\n" " 1 -> start; 2 -> stop\n" " --help|-h print out usage message\n" " --time=TN|-t TN TN (units 100 ms) is max time to perform " "background\n" " operations (def: 0 -> no limit)\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" "Performs a SCSI BACKGROUND CONTROL command. It can start or " "stop\n'advanced background operations'. Operations started by " "this command\n(i.e. when ctl=1) are termed as 'host initiated' " "and allow a resource or\nthin provisioned device (disk) to " "perform garbage collection type operations.\nThese may " "degrade performance while they occur. Hence it is best to\n" "perform this action while the computer is not too busy.\n"); }
/* Returns 0 if successful */ static int process_read_long(int sg_fd, bool do_16, bool pblock, bool correct, uint64_t llba, void * data_out, int xfer_len, int verbose) { int offset, res; const char * ten_or; char b[80]; if (do_16) res = sg_ll_read_long16(sg_fd, pblock, correct, llba, data_out, xfer_len, &offset, true, verbose); else res = sg_ll_read_long10(sg_fd, pblock, correct, (unsigned int)llba, data_out, xfer_len, &offset, true, verbose); ten_or = do_16 ? "16" : "10"; switch (res) { case 0: break; case SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO: pr2serr("<<< device indicates 'xfer_len' should be %d >>>\n", xfer_len - offset); break; default: sg_get_category_sense_str(res, sizeof(b), b, verbose); pr2serr(" SCSI READ LONG (%s): %s\n", ten_or, b); break; } return res; }
static void print_stats() { if (0 != dd_count) pr2serr(" remaining block count=%" PRId64 "\n", dd_count); pr2serr("%" PRId64 "+%d records in\n", in_full - in_partial, in_partial); pr2serr("%" PRId64 "+%d records out\n", out_full - out_partial, out_partial); }
static void list_op_abbrevs() { struct smp_val_name * vnp; pr2serr(" Valid operation abbreviations are:\n"); for (vnp = op_abbrev; vnp->name; ++vnp) pr2serr(" %s\n", vnp->name); }
static int fail_all_paths(int fd, int use_6_byte) { unsigned char fail_paths_pg[308]; struct rdac_legacy_page *rdac_page; struct rdac_expanded_page *rdac_page_exp; struct rdac_page_common *rdac_common = NULL; int res; char b[80]; memset(fail_paths_pg, 0, 308); if (use_6_byte) { memcpy(fail_paths_pg, mode6_hdr, 4); memcpy(fail_paths_pg + 4, block_descriptor, 8); rdac_page = (struct rdac_legacy_page *)(fail_paths_pg + 4 + 8); rdac_page->page_code = RDAC_CONTROLLER_PAGE; rdac_page->page_length = RDAC_CONTROLLER_PAGE_LEN; rdac_common = &rdac_page->attr; } else { memcpy(fail_paths_pg, mode10_hdr, 8); rdac_page_exp = (struct rdac_expanded_page *) (fail_paths_pg + 8); rdac_page_exp->page_code = RDAC_CONTROLLER_PAGE | 0x40; rdac_page_exp->subpage_code = 0x1; sg_put_unaligned_be16(EXPANDED_LUN_SPACE_PAGE_LEN, rdac_page_exp->page_length + 0); rdac_common = &rdac_page_exp->attr; } rdac_common->current_mode_lsb = RDAC_FAIL_ALL_PATHS; rdac_common->quiescence = RDAC_QUIESCENCE_TIME; rdac_common->options = RDAC_FORCE_QUIESCENCE; if (use_6_byte) { res = sg_ll_mode_select6(fd, 1 /* pf */, 0 /* sp */, fail_paths_pg, 118, 1, (do_verbose ? 2 : 0)); } else { res = sg_ll_mode_select10(fd, 1 /* pf */, 0 /* sp */, fail_paths_pg, 308, 1, (do_verbose ? 2: 0)); } switch (res) { case 0: if (do_verbose) pr2serr("fail paths successful\n"); break; default: sg_get_category_sense_str(res, sizeof(b), b, do_verbose); pr2serr("fail paths failed: %s\n", b); break; } return res; }
/* Allocate aligned memory (heap) starting on page boundary */ static unsigned char * my_memalign(int length, unsigned char ** wrkBuffp, const struct opts_t * op) { size_t psz; unsigned char * res; #if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) psz = sysconf(_SC_PAGESIZE); /* POSIX.1 (was getpagesize()) */ #elif defined(SG_LIB_WIN32) psz = win_pagesize(); #else psz = 4096; /* give up, pick likely figure */ #endif #ifdef HAVE_POSIX_MEMALIGN { int err; void * wp = NULL; err = posix_memalign(&wp, psz, length); if (err || (NULL == wp)) { pr2serr("posix_memalign: error [%d], out of memory?\n", err); return NULL; } memset(wp, 0, length); if (wrkBuffp) *wrkBuffp = (unsigned char *)wp; res = (unsigned char *)wp; if (op->verbose > 3) pr2serr("%s: posix, len=%d, wrkBuffp=%p, psz=%d, rp=%p\n", __func__, length, (void *)*wrkBuffp, (int)psz, (void *)res); return res; } #else { unsigned char * wrkBuff; wrkBuff = (unsigned char*)calloc(length + psz, 1); if (NULL == wrkBuff) { if (wrkBuffp) *wrkBuffp = NULL; return NULL; } else if (wrkBuffp) *wrkBuffp = wrkBuff; res = (unsigned char *)(((uintptr_t)wrkBuff + psz - 1) & (~(psz - 1))); if (op->verbose > 3) pr2serr("%s: hack, len=%d, wrkBuffp=%p, psz=%d, rp=%p\n", __func__, length, (void *)*wrkBuffp, (int)psz, (void *)res); return res; } #endif }
static int ll_sync_cache_16(int sg_fd, int sync_nv, int immed, int group, uint64_t lba, unsigned int num_lb, int to_secs, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char sc_cdb[SYNCHRONIZE_CACHE16_CMDLEN] = { SYNCHRONIZE_CACHE16_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (sync_nv) sc_cdb[1] |= 4; /* obsolete in sbc3r35d */ if (immed) sc_cdb[1] |= 2; sg_put_unaligned_be64(lba, sc_cdb + 2); sc_cdb[14] = group & 0x1f; sg_put_unaligned_be32((uint32_t)num_lb, sc_cdb + 10); if (verbose) { pr2serr(" synchronize cache(16) cdb: "); for (k = 0; k < SYNCHRONIZE_CACHE16_CMDLEN; ++k) pr2serr("%02x ", sc_cdb[k]); pr2serr("\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { pr2serr("synchronize cache(16): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, sc_cdb, sizeof(sc_cdb)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); res = do_scsi_pt(ptvp, sg_fd, to_secs, verbose); ret = sg_cmds_process_resp(ptvp, "synchronize cache(16)", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = sense_cat; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; }
/* Invokes a SCSI REPORT TIMESTAMP command. Return of 0 -> success, * various SG_LIB_CAT_* positive values or -1 -> other errors */ static int sg_ll_rep_timestamp(int sg_fd, void * resp, int mx_resp_len, int * residp, int noisy, int verbose) { int k, ret, res, sense_cat; unsigned char rtCmdBlk[REP_TIMESTAMP_CMDLEN] = {SG_MAINTENANCE_IN, REP_TIMESTAMP_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; sg_put_unaligned_be32((uint32_t)mx_resp_len, rtCmdBlk + 6); if (verbose) { pr2serr(" Report timestamp cdb: "); for (k = 0; k < REP_TIMESTAMP_CMDLEN; ++k) pr2serr("%02x ", rtCmdBlk[k]); pr2serr("\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { pr2serr("%s: out of memory\n", __func__); return -1; } set_scsi_pt_cdb(ptvp, rtCmdBlk, sizeof(rtCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "report timestamp", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = sense_cat; break; } } else ret = 0; k = get_scsi_pt_resid(ptvp); if (residp) *residp = k; if ((verbose > 2) && ((mx_resp_len - k) > 0)) { pr2serr("Parameter data returned:\n"); dStrHexErr((const char *)resp, mx_resp_len - k, ((verbose > 3) ? -1 : 1)); } destruct_scsi_pt_obj(ptvp); return ret; }
static void print_modes(void) { const struct mode_s *mp; pr2serr("The modes parameter argument can be numeric (hex or decimal)\n" "or symbolic:\n"); for (mp = modes; mp->mode_string; ++mp) { pr2serr(" %2d (0x%02x) %-16s%s\n", mp->mode, mp->mode, mp->mode_string, mp->comment); } }
/* Invokes the SET TIMESTAMP command. Return of 0 -> success, various * SG_LIB_CAT_* positive values or -1 -> other errors */ static int sg_ll_set_timestamp(int sg_fd, void * paramp, int param_len, int noisy, int verbose) { int k, ret, res, sense_cat; unsigned char stCmdBlk[SET_TIMESTAMP_CMDLEN] = {SG_MAINTENANCE_OUT, SET_TIMESTAMP_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; sg_put_unaligned_be32(param_len, stCmdBlk + 6); if (verbose) { pr2serr(" Set timestamp cdb: "); for (k = 0; k < SET_TIMESTAMP_CMDLEN; ++k) pr2serr("%02x ", stCmdBlk[k]); pr2serr("\n"); if ((verbose > 1) && paramp && param_len) { pr2serr(" set timestamp parameter list:\n"); dStrHexErr((const char *)paramp, param_len, -1); } } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { pr2serr("%s: out of memory\n", __func__); return -1; } set_scsi_pt_cdb(ptvp, stCmdBlk, sizeof(stCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "set timestamp", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = sense_cat; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; }
static void decode_all_sa_s(const unsigned char * rabp, int len, const struct opts_t * op) { if (op->do_hex && (2 != op->do_hex)) { dStrHex((const char *)rabp, len, ((1 == op->do_hex) ? 1 : -1)); return; } switch (op->sa) { case RA_ATTR_VAL_SA: decode_attr_vals(rabp + 4, len - 4, op); break; case RA_ATTR_LIST_SA: decode_attr_list(rabp + 4, len - 4, false, op); break; case RA_LV_LIST_SA: if ((0 == op->quiet) || op->verbose) printf("Logical volume list:\n"); if (len < 4) { pr2serr(">>> response length unexpectedly short: %d bytes\n", len); break; } printf(" First logical volume number: %u\n", rabp[2]); printf(" Number of logical volumes available: %u\n", rabp[3]); break; case RA_PART_LIST_SA: if ((0 == op->quiet) || op->verbose) printf("Partition number list:\n"); if (len < 4) { pr2serr(">>> response length unexpectedly short: %d bytes\n", len); break; } printf(" First partition number: %u\n", rabp[2]); printf(" Number of partitions available: %u\n", rabp[3]); break; case RA_SMC2_SA: printf("Used by SMC-2, not information, output in hex:\n"); dStrHex((const char *)rabp, len, 0); break; case RA_SUP_ATTR_SA: decode_attr_list(rabp + 4, len - 4, true, op); break; default: printf("Unrecognized service action [0x%x], response in hex:\n", op->sa); dStrHex((const char *)rabp, len, 0); break; } }
/* Invokes a SCSI BACKGROUND CONTROL command (SBC-4). Return of 0 -> success, * various SG_LIB_CAT_* positive values or -1 -> other errors */ static int sg_ll_background_control(int sg_fd, unsigned int bo_ctl, unsigned int bo_time, bool noisy, int verbose) { int k, ret, res, sense_cat; uint8_t bcCDB[16] = {SG_SERVICE_ACTION_IN_16, BACKGROUND_CONTROL_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (bo_ctl) bcCDB[2] |= (bo_ctl & 0x3) << 6; if (bo_time) bcCDB[3] = bo_time; if (verbose) { pr2serr(" %s cdb: ", cmd_name); for (k = 0; k < (int)sizeof(bcCDB); ++k) pr2serr("%02x ", bcCDB[k]); pr2serr("\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { pr2serr("%s: out of memory\n", cmd_name); return -1; } set_scsi_pt_cdb(ptvp, bcCDB, sizeof(bcCDB)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cmd_name, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ret = sg_convert_errno(get_scsi_pt_os_err(ptvp)); else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = sense_cat; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; }
static void print_modes(void) { const struct mode_s * mp; pr2serr("The modes parameter argument can be numeric (hex or decimal)\n" "or symbolic:\n"); for (mp = mode_arr; mp->mode_string; ++mp) { pr2serr(" %3d [0x%02x] %-18s%s\n", mp->mode, mp->mode, mp->mode_string, mp->comment); } pr2serr("\nAdditionally '--bpw=<val>,act' does a activate deferred " "microcode after a\nsuccessful multipart dmc_offs_defer mode " "download.\n"); }
static void usage(void) { pr2serr("Usage: smp_rep_phy_sata [--affiliation=AC] [--help] [--hex]\n" " [--interface=PARAMS] [--phy=ID] " "[--raw]\n" " [--sa=SAS_ADDR] [--verbose] [--version] " "[--zero]\n" " SMP_DEVICE[,N]\n" " where:\n" " --affiliation=AC|-a AC relative identifier of affiliation " "context\n" " (def: 0)\n" " --help|-h print out usage message\n" " --hex|-H print response in hexadecimal\n" " --interface=PARAMS|-I PARAMS specify or override " "interface\n" " --phy=ID|-p ID phy identifier (def: 0)\n" " --raw|-r output response in binary\n" " --sa=SAS_ADDR|-s SAS_ADDR SAS address of SMP " "target (use leading\n" " '0x' or trailing 'h'). " "Depending on\n" " the interface, may not be " "needed\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n" " --zero|-z zero Allocated Response Length " "field,\n" " may be required prior to SAS-2\n\n" "Performs a SMP REPORT PHY SATA function\n" ); }
static int skip(int fd, off_t offset) { off_t remain; char buffer[512]; if (lseek(fd, offset, SEEK_SET) >= 0) { return 0; } // lseek failed; fall back to reading and discarding data remain = offset; while (remain > 0) { ssize_t amount, done; amount = (remain < (off_t)sizeof(buffer)) ? remain : (off_t)sizeof(buffer); done = read(fd, buffer, amount); if (done < 0) { perror("Error reading input data"); return SG_LIB_FILE_ERROR; } else if (done == 0) { pr2serr("EOF on input file/stream\n"); return SG_LIB_FILE_ERROR; } else { remain -= done; } } return 0; }
static void usage() { pr2serr("Usage: sg_read_buffer [--16] [--help] [--hex] [--id=ID] " "[--length=LEN]\n" " [--long] [--mode=MO] [--offset=OFF] " "[--raw]\n" " [--readonly] [--specific=MS] [--verbose] " "[--version]\n" " DEVICE\n" " where:\n" " --16|-L issue READ BUFFER(16) (def: 10)\n" " --help|-h print out usage message\n" " --hex|-H print output in hex\n" " --id=ID|-i ID buffer identifier (0 (default) to 255)\n" " --length=LEN|-l LEN length in bytes to read (def: 4)\n" " --long|-L issue READ BUFFER(16) (def: 10)\n" " --mode=MO|-m MO read buffer mode, MO is number or " "acronym (def: 0)\n" " --offset=OFF|-o OFF buffer offset (unit: bytes, def: 0)\n" " --raw|-r output response to stdout\n" " --readonly|-R open DEVICE read-only (def: read-write)\n" " --specific=MS|-S MS mode specific value; 3 bit field (0 " "to 7)\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" "Performs a SCSI READ BUFFER (10 or 16) command. Use '-m xxx' to " "list\navailable modes. Numbers given in options are decimal " "unless they have\na hex indicator (e.g. a leading '0x').\n" ); }
static void usage(void) { pr2serr("Usage: smp_conf_route_info [--disable] [--expected=EX] [--help] " "[--hex]\n" " [--index=IN] [--interface=PARAMS] " "[--phy=ID]\n" " [--raw] [--routed=R_SAS_ADDR] " "[--sa=SAS_ADDR]\n" " [--verbose] [--version] " "SMP_DEVICE[,N]\n" " where:\n" " --disable|-d disable expander route entry\n" " --expected=EX|-E EX set expected expander change " "count to EX\n" " --help|-h print out usage message\n" " --hex|-H print response in hexadecimal\n" " --index=IN|-i IN expander route index (def: 0)\n" " --interface=PARAMS|-I PARAMS specify or override " "interface\n" " --phy=ID|-p ID phy identifier (def: 0)\n" " --raw|-r output response in binary\n" " --routed=R_SAS_ADDR|-R R_SAS_ADDR routed SAS " "address\n" " --sa=SAS_ADDR|-s SAS_ADDR SAS address of SMP " "target (use leading\n" " '0x' or trailing 'h'). " "Depending on\n" " the interface, may not be " "needed\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" "Performs a SMP CONFIGURE ROUTE INFORMATION function\n" ); }
static void usage() { pr2serr("Usage: sg_read_long [--16] [--correct] [--help] [--lba=LBA] " "[--out=OF]\n" " [--pblock] [--readonly] [--verbose] " "[--version]\n" " [--xfer_len=BTL] DEVICE\n" " where:\n" " --16|-S do READ LONG(16) (default: " "READ LONG(10))\n" " --correct|-c use ECC to correct data " "(default: don't)\n" " --help|-h print out usage message\n" " --lba=LBA|-l LBA logical block address" " (default: 0)\n" " --out=OF|-o OF output in binary to file named OF\n" " --pblock|-p fetch physical block containing LBA\n" " --readonly|-r open DEVICE read-only (def: open it " "read-write)\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and" " exit\n" " --xfer_len=BTL|-x BTL byte transfer length (< 10000)" " default 520\n\n" "Perform a SCSI READ LONG (10 or 16) command. Reads a single " "block with\nassociated ECC data. The user data could be " "encoded or encrypted.\n"); }
static void usage(void) { pr2serr("Usage: smp_rep_zone_man_pass [--fpass=FP] [--help] [--hex]\n" " [--interface=PARAMS] [--phex] " "[--raw]\n" " [--report=RT] [--sa=SAS_ADDR] " "[--verbose]\n" " [--version] SMP_DEVICE[,N]\n" " where:\n" " --fpass=FP|-F FP FP is file to write password to\n" " (default: stdout)\n" " --help|-h print out usage message\n" " --hex|-H print response in hexadecimal\n" " --interface=PARAMS|-I PARAMS specify or override " "interface\n" " --phex|-p output password (only) in hex\n" " (default: ASCII between single quotes)\n" " --raw|-r output response in binary\n" " --report=RT|-R RT report type: 0 (default) -> current\n" " 2 -> saved; 3 -> default manager " "password\n" " --sa=SAS_ADDR|-s SAS_ADDR SAS address of SMP " "target (use leading\n" " '0x' or trailing 'h'). " "Depending on\n" " the interface, may not be " "needed\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" "Performs a SMP REPORT ZONE MANAGER PASSWORD function\n" ); }
static void usage() { pr2serr("Usage: sg_sat_identify [--ck_cond] [--extend] [--help] [--hex] " "[--ident]\n" " [--len=CLEN] [--packet] [--raw] " "[--readonly]\n" " [--verbose] [--version] DEVICE\n" " where:\n" " --ck_cond|-c sets ck_cond bit in cdb (def: 0)\n" " --extend|-e sets extend bit in cdb (def: 0)\n" " --help|-h print out usage message then exit\n" " --hex|-H output response in hex\n" " --ident|-i output WWN prefixed by 0x, if not " "available output\n" " 0x0000000000000000\n" " --len=CLEN| -l CLEN CLEN is cdb length: 12, 16 or 32 " "bytes\n" " (default: 16)\n" " --packet|-p do IDENTIFY PACKET DEVICE (def: IDENTIFY " "DEVICE)\n" " command\n" " --raw|-r output response in binary to stdout\n" " --readonly|-R open DEVICE read-only (def: read-write)\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" "Performs a ATA IDENTIFY (PACKET) DEVICE command via a SAT " "layer using\na SCSI ATA PASS-THROUGH(12), (16) or (32) command. " "Only SAT layers\ncompliant with SAT-4 revision 5 or later will " "support the SCSI ATA\nPASS-THROUGH(32) command.\n"); }
static void usage() { pr2serr("Usage: sg_sat_identify [--ck_cond] [--extend] [--help] [--hex] " "[--ident]\n" " [--len=16|12] [--packet] [--raw] " "[--readonly]\n" " [--verbose] [--version] DEVICE\n" " where:\n" " --ck_cond|-c sets ck_cond bit in cdb (def: 0)\n" " --extend|-e sets extend bit in cdb (def: 0)\n" " --help|-h print out usage message then exit\n" " --hex|-H output response in hex\n" " --ident|-i output WWN prefixed by 0x, if not " "available output\n" " 0x0000000000000000\n" " --len=16|12 | -l 16|12 cdb length: 16 or 12 bytes " "(default: 16)\n" " --packet|-p do IDENTIFY PACKET DEVICE (def: IDENTIFY " "DEVICE) command\n" " --raw|-r output response in binary to stdout\n" " --readonly|-R open DEVICE read-only (def: read-write)\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" "Performs a ATA IDENTIFY (PACKET) DEVICE command via a SAT " "layer\n"); }
static void usage() { pr2serr("Usage: sg_sync [--16] [--count=COUNT] [--group=GN] [--help] " "[--immed]\n" " [--lba=LBA] [--sync-nv] [--timeout=SEC] " "[--verbose]\n" " [--version] DEVICE\n" " where:\n" " --16|-S calls SYNCHRONIZE CACHE(16) (def: is " "10 byte\n" " variant)\n" " --count=COUNT|-c COUNT number of blocks to sync (def: 0 " "which\n" " implies rest of device)\n" " --group=GN|-g GN set group number field to GN (def: 0)\n" " --help|-h print out usage message\n" " --immed|-i command returns immediately when set " "else wait\n" " for 'sync' to complete\n" " --lba=LBA|-l LBA logical block address to start sync " "operation\n" " from (def: 0)\n" " --sync-nv|-s synchronize to non-volatile storage " "(if distinct\n" " from medium). Obsolete in sbc3r35d.\n" " --timeout=SEC|-t SEC command timeout in seconds, only " "active\n" " if '--16' given (def: 60 seconds)\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" "Performs a SCSI SYNCHRONIZE CACHE(10 or 16) command\n"); }
static void usage(void) { pr2serr("Usage: smp_read_gpio [--count=CO] [--enhanced] [--help] " "[--hex]\n" " [--index=IN] [--interface=PARAMS] " "[--raw]\n" " [--sa=SAS_ADDR] [type=TY] [--verbose] " "[--version]\n" " SMP_DEVICE[,N]\n" " where:\n" " --count=CO|-c CO register count (dwords to read) " "(def: 1)\n" " --enhanced|-E use READ GPIO REGISTER ENHANCED " "function\n" " --help|-h print out usage message\n" " --hex|-H print response in hexadecimal\n" " --index=IN|-i IN register index (def: 0)\n" " --interface=PARAMS|-I PARAMS specify or override " "interface\n" " --raw|-r output response in binary\n" " --sa=SAS_ADDR|-s SAS_ADDR SAS address of SMP target " "(use leading\n" " '0x' or trailing 'h'). " "Depending on\n" " the interface, may not be " "needed\n" " --type=TY|-t TY register type (def: 0 (GPIO_CFG))\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" "Performs a SMP READ GPIO REGISTER (default) or READ GPIO " "REGISTER ENHANCED\nfunction\n" ); }
/* Return of 0 -> success, see sg_ll_read_capacity*() otherwise */ static int scsi_read_capacity(int sg_fd, int64_t * num_sect, int * sect_sz) { int res; unsigned int ui; unsigned char rcBuff[RCAP16_REPLY_LEN]; int verb; verb = (verbose ? verbose - 1: 0); res = sg_ll_readcap_10(sg_fd, 0, 0, rcBuff, READ_CAP_REPLY_LEN, 0, verb); if (0 != res) return res; if ((0xff == rcBuff[0]) && (0xff == rcBuff[1]) && (0xff == rcBuff[2]) && (0xff == rcBuff[3])) { res = sg_ll_readcap_16(sg_fd, 0, 0, rcBuff, RCAP16_REPLY_LEN, 0, verb); if (0 != res) return res; *num_sect = sg_get_unaligned_be64(rcBuff + 0) + 1; *sect_sz = sg_get_unaligned_be32(rcBuff + 8); } else { ui = sg_get_unaligned_be32(rcBuff + 0); /* take care not to sign extend values > 0x7fffffff */ *num_sect = (int64_t)ui + 1; *sect_sz = sg_get_unaligned_be32(rcBuff + 4); } if (verbose) pr2serr(" number of blocks=%" PRId64 " [0x%" PRIx64 "], block " "size=%d\n", *num_sect, *num_sect, *sect_sz); return 0; }
static void usage(void) { pr2serr("Usage: smp_rep_manufacturer [--help] [--hex] " "[--interface=PARAMS] [--raw]\n" " [--sa=SAS_ADDR] [--verbose] " "[--version]\n" " [--zero] SMP_DEVICE[,N]\n" " where:\n" " --help|-h print out usage message\n" " --hex|-H print response in hexadecimal\n" " --interface=PARAMS|-I PARAMS specify or override " "interface\n" " --raw|-r output response in binary\n" " --sa=SAS_ADDR|-s SAS_ADDR SAS address of SMP " "target (use leading\n" " '0x' or trailing 'h'). " "Depending on\n" " the interface, may not be " "needed\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n" " --zero|-z zero Allocated Response Length " "field,\n" " may be required prior to SAS-2\n\n" "Performs a SMP REPORT MANUFACTURER INFORMATION function\n" ); }
static void usage() { pr2serr("Usage: sg_read_attr [--cache] [--element=EA] [--enumerate] " "[--filter=FL]\n" " [--first=FAI] [--help] [--hex] [--in=FN] " "[--lvn=LVN]\n" " [--maxlen=LEN] [--partition=PN] [--quiet] " "[--raw]\n" " [--readonly] [--sa=SA] [--verbose] " "[--version]\n" " DEVICE\n"); pr2serr(" where:\n" " --cache|-c set CACHE bit in cdn (def: clear)\n" " --enumerate|-e enumerate known attributes and service " "actions\n" " --element=EA|-E EA EA is placed in 'element address' " "field in\n" " cdb [SMC-3] (def: 0)\n" " --filter=FL|-f FL FL is parameter code to match (def: " "-1 -> all)\n" " --first=FAI|-F FAI FAI is placed in 'first attribute " "identifier'\n" " field in cdb (def: 0)\n" " --help|-h print out usage message\n" " --hex|-H output response in hexadecimal; used " "twice\n" " shows decoded values in hex\n" " --in=FN|-i FN FN is a filename containing attribute " "values in\n" " ASCII hex or binary if --raw also " "given\n" " --lvn=LVN|-l LVN logical volume number (LVN) (def:0)\n" " --maxlen=LEN|-m LEN max response length (allocation " "length in cdb)\n" " (def: 0 -> 8192 bytes)\n" " --partition=PN|-p PN partition number (PN) (def:0)\n" " --quiet|-q reduce the amount of output, can use " "more than once\n" " --raw|-r output response in binary\n" " --readonly|-R open DEVICE read-only (def: read-write)\n" " --sa=SA|-s SA SA is service action (def: 0)\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" "Performs a SCSI READ ATTRIBUTE command. It is typically used " "on tape\nsystems.\n"); }