Index: src/sbin/camcontrol/camcontrol.8 =================================================================== RCS file: /home/ncvs/src/sbin/camcontrol/camcontrol.8,v retrieving revision 1.38 diff -u -p -r1.38 camcontrol.8 --- src/sbin/camcontrol/camcontrol.8 3 Jul 2004 00:13:43 -0000 1.38 +++ src/sbin/camcontrol/camcontrol.8 6 Oct 2004 09:17:37 -0000 @@ -95,6 +95,7 @@ .Op Fl P Ar pgctl .Op Fl b | Fl e .Op Fl d +.Op Fl s .Nm .Ic cmd .Op device id @@ -376,6 +377,9 @@ and/or edit. This argument is mandatory unless .Fl l is specified. +.It Fl s +This forces the use of a 10-byte MODE SENSE or MODE SELECT command, which is +necessary for certain kinds of devices. .It Fl P Ar pgctl This allows the user to specify the page control field. Possible values are: Index: src/sbin/camcontrol/camcontrol.c =================================================================== RCS file: /home/ncvs/src/sbin/camcontrol/camcontrol.c,v retrieving revision 1.52 diff -u -p -r1.52 camcontrol.c --- src/sbin/camcontrol/camcontrol.c 3 Mar 2004 01:51:24 -0000 1.52 +++ src/sbin/camcontrol/camcontrol.c 6 Oct 2004 09:13:52 -0000 @@ -139,7 +139,7 @@ struct camcontrol_opts option_table[] = {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL}, #ifndef MINIMALISTIC {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL}, - {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"}, + {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:sP:"}, {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"}, {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, @@ -1586,7 +1586,8 @@ reassignblocks(struct cam_device *device #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) + int dbd, int retry_count, int timeout, u_int8_t *data, int datalen, + int force10bytes) { union ccb *ccb; int retval; @@ -1599,7 +1600,7 @@ mode_sense(struct cam_device *device, in bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); - scsi_mode_sense(&ccb->csio, + scsi_mode_sense_len(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ MSG_SIMPLE_Q_TAG, @@ -1608,6 +1609,7 @@ mode_sense(struct cam_device *device, in /* page */ mode_page, /* param_buf */ data, /* param_len */ datalen, + /* minimum_cmd_size */ force10bytes ? 10 : 0, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); @@ -1636,7 +1638,7 @@ mode_sense(struct cam_device *device, in void mode_select(struct cam_device *device, int save_pages, int retry_count, - int timeout, u_int8_t *data, int datalen) + int timeout, u_int8_t *data, int datalen, int force10bytes) { union ccb *ccb; int retval; @@ -1649,7 +1651,7 @@ mode_select(struct cam_device *device, i bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); - scsi_mode_select(&ccb->csio, + scsi_mode_select_len(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ MSG_SIMPLE_Q_TAG, @@ -1657,6 +1659,7 @@ mode_select(struct cam_device *device, i /* save_pages */ save_pages, /* param_buf */ data, /* param_len */ datalen, + /* minimum_cmd_size */ force10bytes ? 10 : 0, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); @@ -1690,7 +1693,7 @@ modepage(struct cam_device *device, int int retry_count, int timeout) { int c, mode_page = -1, page_control = 0; - int binary = 0, list = 0; + int binary = 0, list = 0, force10bytes = 0; while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { @@ -1711,6 +1714,9 @@ modepage(struct cam_device *device, int if (mode_page < 0) errx(1, "invalid mode page %d", mode_page); break; + case 's': + force10bytes = 1; + break; case 'P': page_control = strtol(optarg, NULL, 0); if ((page_control < 0) || (page_control > 3)) @@ -1728,11 +1734,11 @@ modepage(struct cam_device *device, int if (list) { mode_list(device, page_control, arglist & CAM_ARG_DBD, - retry_count, timeout); + retry_count, timeout, force10bytes); } else { mode_edit(device, mode_page, page_control, arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary, - retry_count, timeout); + retry_count, timeout, force10bytes); } } @@ -3166,7 +3172,7 @@ usage(int verbose) #ifndef MINIMALISTIC " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n" " camcontrol modepage [dev_id][generic args] <-m page | -l>\n" -" [-P pagectl][-e | -b][-d]\n" +" [-P pagectl][-e | -b][-d][-s]\n" " camcontrol cmd [dev_id][generic args] <-c cmd [args]>\n" " [-i len fmt|-o len fmt [args]]\n" " camcontrol debug [-I][-P][-T][-S][-X][-c]\n" Index: src/sbin/camcontrol/camcontrol.h =================================================================== RCS file: /home/ncvs/src/sbin/camcontrol/camcontrol.h,v retrieving revision 1.4 diff -u -p -r1.4 camcontrol.h --- src/sbin/camcontrol/camcontrol.h 8 Aug 2000 06:24:15 -0000 1.4 +++ src/sbin/camcontrol/camcontrol.h 6 Oct 2004 09:14:03 -0000 @@ -42,13 +42,14 @@ struct get_hook 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); + int datalen, int force10bytes); void mode_select(struct cam_device *device, int save_pages, int retry_count, - int timeout, u_int8_t *data, int datalen); + int timeout, u_int8_t *data, int datalen, int force10bytes); void mode_edit(struct cam_device *device, int page, int page_control, int dbd, - int edit, int binary, int retry_count, int timeout); + int edit, int binary, int retry_count, int timeout, + int force10bytes); void mode_list(struct cam_device *device, int page_control, int dbd, - int retry_count, int timeout); + int retry_count, int timeout, int force10bytes); char *cget(void *hook, char *name); int iget(void *hook, char *name); void arg_put(void *hook, int letter, void *arg, int count, char *name); Index: src/sbin/camcontrol/modeedit.c =================================================================== RCS file: /home/ncvs/src/sbin/camcontrol/modeedit.c,v retrieving revision 1.17 diff -u -p -r1.17 modeedit.c --- src/sbin/camcontrol/modeedit.c 22 Jan 2004 07:23:35 -0000 1.17 +++ src/sbin/camcontrol/modeedit.c 6 Oct 2004 09:17:07 -0000 @@ -110,10 +110,11 @@ static int editentry_set(char *name, c int editonly); static void editlist_populate(struct cam_device *device, int modepage, int page_control, - int dbd, int retries, int timeout); + int dbd, int retries, int timeout, + int force10bytes); static void editlist_save(struct cam_device *device, int modepage, int page_control, int dbd, int retries, - int timeout); + int timeout, int force10bytes); static void nameentry_create(int pagenum, char *name); static struct pagename *nameentry_lookup(int pagenum); static int load_format(const char *pagedb_path, int page); @@ -122,7 +123,7 @@ static int modepage_read(FILE *file); static void modepage_edit(void); static void modepage_dump(struct cam_device *device, int page, int page_control, int dbd, int retries, - int timeout); + int timeout, int force10bytes); static void cleanup_editfile(void); @@ -527,7 +528,7 @@ load_format(const char *pagedb_path, int static void editlist_populate(struct cam_device *device, int modepage, int page_control, - int dbd, int retries, int timeout) + int dbd, int retries, int timeout, int force10bytes) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ u_int8_t *mode_pars; /* Pointer to modepage params. */ @@ -538,7 +539,7 @@ editlist_populate(struct cam_device *dev /* Fetch changeable values; use to build initial editlist. */ mode_sense(device, modepage, 1, dbd, retries, timeout, data, - sizeof(data)); + sizeof(data), force10bytes); mh = (struct scsi_mode_header_6 *)data; mph = MODE_PAGE_HEADER(mh); @@ -550,14 +551,14 @@ editlist_populate(struct cam_device *dev /* Fetch the current/saved values; use to set editentry values. */ mode_sense(device, modepage, page_control, dbd, retries, timeout, data, - sizeof(data)); + sizeof(data), force10bytes); buff_decode_visit(mode_pars, mh->data_length, format, editentry_update, 0); } static void editlist_save(struct cam_device *device, int modepage, int page_control, - int dbd, int retries, int timeout) + int dbd, int retries, int timeout, int force10bytes) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ u_int8_t *mode_pars; /* Pointer to modepage params. */ @@ -575,7 +576,7 @@ editlist_save(struct cam_device *device, * now, we need mode_sense to find out the page length. */ mode_sense(device, modepage, page_control, dbd, retries, timeout, data, - sizeof(data)); + sizeof(data), force10bytes); /* Initial headers & offsets. */ mh = (struct scsi_mode_header_6 *)data; @@ -607,7 +608,8 @@ editlist_save(struct cam_device *device, mode_select(device, (page_control << PAGE_CTRL_SHIFT == SMS_PAGE_CTRL_SAVED), retries, timeout, (u_int8_t *)mh, - sizeof(*mh) + mh->blk_desc_len + sizeof(*mph) + mph->page_length); + sizeof(*mh) + mh->blk_desc_len + sizeof(*mph) + mph->page_length, + force10bytes); } static int @@ -777,7 +779,7 @@ modepage_edit(void) static void modepage_dump(struct cam_device *device, int page, int page_control, int dbd, - int retries, int timeout) + int retries, int timeout, int force10bytes) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ u_int8_t *mode_pars; /* Pointer to modepage params. */ @@ -786,7 +788,7 @@ modepage_dump(struct cam_device *device, int indx; /* Index for scanning mode params. */ mode_sense(device, page, page_control, dbd, retries, timeout, data, - sizeof(data)); + sizeof(data), force10bytes); mh = (struct scsi_mode_header_6 *)data; mph = MODE_PAGE_HEADER(mh); @@ -812,7 +814,8 @@ cleanup_editfile(void) void mode_edit(struct cam_device *device, int page, int page_control, int dbd, - int edit, int binary, int retry_count, int timeout) + int edit, int binary, int retry_count, int timeout, + int force10bytes) { const char *pagedb_path; /* Path to modepage database. */ @@ -842,7 +845,7 @@ mode_edit(struct cam_device *device, int } editlist_populate(device, page, page_control, dbd, retry_count, - timeout); + timeout, force10bytes); } if (edit) { @@ -852,11 +855,11 @@ mode_edit(struct cam_device *device, int "(current) or page 3 (saved values)"); modepage_edit(); editlist_save(device, page, page_control, dbd, retry_count, - timeout); + timeout, force10bytes); } else if (binary || STAILQ_EMPTY(&editlist)) { /* Display without formatting information. */ modepage_dump(device, page, page_control, dbd, retry_count, - timeout); + timeout, force10bytes); } else { /* Display with format. */ modepage_write(stdout, 0); @@ -865,7 +868,7 @@ mode_edit(struct cam_device *device, int void mode_list(struct cam_device *device, int page_control, int dbd, - int retry_count, int timeout) + int retry_count, int timeout, int force10bytes) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ u_int8_t *mode_pars; /* Pointer to modepage params. */ @@ -885,7 +888,7 @@ mode_list(struct cam_device *device, int /* Build the list of all mode pages by querying the "all pages" page. */ mode_sense(device, SMS_ALL_PAGES_PAGE, page_control, dbd, retry_count, - timeout, data, sizeof(data)); + timeout, data, sizeof(data), force10bytes); mh = (struct scsi_mode_header_6 *)data; len = mh->blk_desc_len; /* Skip block descriptors. */