diff options
Diffstat (limited to 'sbin/camcontrol/camcontrol.c')
-rw-r--r-- | sbin/camcontrol/camcontrol.c | 72 |
1 files changed, 40 insertions, 32 deletions
diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index cae7ec2..0050c3b 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -122,12 +122,9 @@ typedef enum { CAM_ARG_GET_STDINQ = 0x00002000, CAM_ARG_GET_XFERRATE = 0x00004000, CAM_ARG_INQ_MASK = 0x00007000, - CAM_ARG_MODE_EDIT = 0x00008000, - CAM_ARG_PAGE_CNTL = 0x00010000, CAM_ARG_TIMEOUT = 0x00020000, CAM_ARG_CMD_IN = 0x00040000, CAM_ARG_CMD_OUT = 0x00080000, - CAM_ARG_DBD = 0x00100000, CAM_ARG_ERR_RECOVER = 0x00200000, CAM_ARG_RETRIES = 0x00400000, CAM_ARG_START_UNIT = 0x00800000, @@ -3982,8 +3979,8 @@ reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks) #ifndef MINIMALISTIC void -mode_sense(struct cam_device *device, int mode_page, int page_control, - int dbd, int retry_count, int timeout, u_int8_t *data, int datalen) +mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage, + int retry_count, int timeout, u_int8_t *data, int datalen) { union ccb *ccb; int retval; @@ -3995,15 +3992,17 @@ mode_sense(struct cam_device *device, int mode_page, int page_control, CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); - scsi_mode_sense(&ccb->csio, + scsi_mode_sense_subpage(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ MSG_SIMPLE_Q_TAG, /* dbd */ dbd, - /* page_code */ page_control << 6, - /* page */ mode_page, + /* pc */ pc << 6, + /* page */ page, + /* subpage */ subpage, /* param_buf */ data, /* param_len */ datalen, + /* minimum_cmd_size */ 0, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); @@ -4084,8 +4083,9 @@ void modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { - int c, mode_page = -1, page_control = 0; - int binary = 0, list = 0; + char *str_subpage; + int c, page = -1, subpage = -1, pc = 0; + int binary = 0, dbd = 0, edit = 0, list = 0; while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { @@ -4093,40 +4093,44 @@ modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, binary = 1; break; case 'd': - arglist |= CAM_ARG_DBD; + dbd = 1; break; case 'e': - arglist |= CAM_ARG_MODE_EDIT; + edit = 1; break; case 'l': - list = 1; + list++; break; case 'm': - mode_page = strtol(optarg, NULL, 0); - if (mode_page < 0) - errx(1, "invalid mode page %d", mode_page); + str_subpage = optarg; + strsep(&str_subpage, ","); + page = strtol(optarg, NULL, 0); + if (str_subpage) + subpage = strtol(str_subpage, NULL, 0); + else + subpage = 0; + if (page < 0) + errx(1, "invalid mode page %d", page); + if (subpage < 0) + errx(1, "invalid mode subpage %d", subpage); break; case 'P': - page_control = strtol(optarg, NULL, 0); - if ((page_control < 0) || (page_control > 3)) - errx(1, "invalid page control field %d", - page_control); - arglist |= CAM_ARG_PAGE_CNTL; + pc = strtol(optarg, NULL, 0); + if ((pc < 0) || (pc > 3)) + errx(1, "invalid page control field %d", pc); break; default: break; } } - if (mode_page == -1 && list == 0) + if (page == -1 && list == 0) errx(1, "you must specify a mode page!"); - if (list) { - mode_list(device, page_control, arglist & CAM_ARG_DBD, - retry_count, timeout); + if (list != 0) { + mode_list(device, dbd, pc, list > 1, retry_count, timeout); } else { - mode_edit(device, mode_page, page_control, - arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary, + mode_edit(device, dbd, pc, page, subpage, edit, binary, retry_count, timeout); } } @@ -4141,7 +4145,7 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, u_int8_t cdb[20]; u_int8_t atacmd[12]; struct get_hook hook; - int c, data_bytes = 0; + int c, data_bytes = 0, valid_bytes; int cdb_len = 0; int atacmd_len = 0; int dmacmd = 0; @@ -4445,16 +4449,20 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, } } + if (cdb_len) + valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid; + else + valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid; if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) && (arglist & CAM_ARG_CMD_IN) - && (data_bytes > 0)) { + && (valid_bytes > 0)) { if (fd_data == 0) { - buff_decode_visit(data_ptr, data_bytes, datastr, + buff_decode_visit(data_ptr, valid_bytes, datastr, arg_put, NULL); fprintf(stdout, "\n"); } else { ssize_t amt_written; - int amt_to_write = data_bytes; + int amt_to_write = valid_bytes; u_int8_t *buf_ptr = data_ptr; for (amt_written = 0; (amt_to_write > 0) && @@ -4469,7 +4477,7 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, } else if ((amt_written == 0) && (amt_to_write > 0)) { warnx("only wrote %u bytes out of %u", - data_bytes - amt_to_write, data_bytes); + valid_bytes - amt_to_write, valid_bytes); } } } |