Author: imp
Date: Tue Mar 12 04:57:05 2019
New Revision: 345051
URL: https://svnweb.freebsd.org/changeset/base/345051

Log:
  Add -l to camcontrol readcap.
  
  The -l flag sends only the READ CAPACITY (16) sevice action. Normally
  we send the READ CAPACITY (10) command, and only send RC16 when the
  capacity is larger than 2TB (since that's the max RC10 can
  report). However, some badly programmed drives report different
  numbers for RC10 and RC16. This can be hard to diagnose, but generally
  there's a "Logical block address out of range" error when RC16 reports
  a larger number than RC10 and the RC10 number is the correct one. By
  comparing the output of readcap with and without the -l argmuent, one
  can determine if there's a mismatch and if the DA_Q_NO_RC16 quirk is
  needed.
  
  Reviewed by: ken@
  Differential Revision: https://reviews.freebsd.org/D19536

Modified:
  head/sbin/camcontrol/camcontrol.8
  head/sbin/camcontrol/camcontrol.c

Modified: head/sbin/camcontrol/camcontrol.8
==============================================================================
--- head/sbin/camcontrol/camcontrol.8   Tue Mar 12 04:49:59 2019        
(r345050)
+++ head/sbin/camcontrol/camcontrol.8   Tue Mar 12 04:57:05 2019        
(r345051)
@@ -78,6 +78,7 @@
 .Op Fl b
 .Op Fl h
 .Op Fl H
+.Op Fl l
 .Op Fl N
 .Op Fl q
 .Op Fl s
@@ -544,6 +545,11 @@ or
 .Fl b .
 .It Fl H
 Print out the device size in human readable (base 10, 1K == 1000) format.
+.It Fl l
+Skip sending the SCSI READ CAPACITY (10) command.
+Send only the SCSI READ CAPACITY (16) service action and report
+its results.
+When the two do not match, a quirk is needed to resolve the ambiguity.
 .It Fl N
 Print out the number of blocks in the device instead of the last logical
 block.

Modified: head/sbin/camcontrol/camcontrol.c
==============================================================================
--- head/sbin/camcontrol/camcontrol.c   Tue Mar 12 04:49:59 2019        
(r345050)
+++ head/sbin/camcontrol/camcontrol.c   Tue Mar 12 04:57:05 2019        
(r345051)
@@ -203,7 +203,7 @@ static struct camcontrol_opts option_table[] = {
        {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
        {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
        {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
-       {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
+       {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
        {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
 #endif /* MINIMALISTIC */
        {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
@@ -7162,7 +7162,7 @@ scsireadcapacity(struct cam_device *device, int argc, 
                 char *combinedopt, int task_attr, int retry_count, int timeout)
 {
        union ccb *ccb;
-       int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
+       int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, 
longonly;
        struct scsi_read_capacity_data rcap;
        struct scsi_read_capacity_data_long rcaplong;
        uint64_t maxsector;
@@ -7172,6 +7172,7 @@ scsireadcapacity(struct cam_device *device, int argc, 
 
        blocksizeonly = 0;
        humanize = 0;
+       longonly = 0;
        numblocks = 0;
        quiet = 0;
        sizeonly = 0;
@@ -7200,6 +7201,9 @@ scsireadcapacity(struct cam_device *device, int argc, 
                        humanize++;
                        baseten++;
                        break;
+               case 'l':
+                       longonly++;
+                       break;
                case 'N':
                        numblocks++;
                        break;
@@ -7242,6 +7246,9 @@ scsireadcapacity(struct cam_device *device, int argc, 
                goto bailout;
        }
 
+       if (longonly != 0)
+               goto long_only;
+
        scsi_read_capacity(&ccb->csio,
                           /*retries*/ retry_count,
                           /*cbfcnp*/ NULL,
@@ -7284,6 +7291,7 @@ scsireadcapacity(struct cam_device *device, int argc, 
        if (maxsector != 0xffffffff)
                goto do_print;
 
+long_only:
        scsi_read_capacity_16(&ccb->csio,
                              /*retries*/ retry_count,
                              /*cbfcnp*/ NULL,
@@ -9515,7 +9523,7 @@ usage(int printlong)
 "        camcontrol identify   [dev_id][generic args] [-v]\n"
 "        camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
 "        camcontrol readcap    [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
-"                              [-q] [-s]\n"
+"                              [-q] [-s] [-l]\n"
 "        camcontrol start      [dev_id][generic args]\n"
 "        camcontrol stop       [dev_id][generic args]\n"
 "        camcontrol load       [dev_id][generic args]\n"
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to