Print this page
10564 Convert uscsi(7I) to mandoc

Split Close
Expand all
Collapse all
          --- old/usr/src/man/man7i/uscsi.7i.man.txt
          +++ new/usr/src/man/man7i/uscsi.7i.man.txt
   1    1  USCSI(7I)                       Ioctl Requests                       USCSI(7I)
   2    2  
   3      -
   4      -
   5    3  NAME
   6      -       uscsi - user SCSI command interface
        4 +     uscsi - user SCSI command interface
   7    5  
   8    6  SYNOPSIS
   9      -       #include <sys/scsi/impl/uscsi.h>
        7 +     #include <sys/scsi/impl/uscsi.h>
  10    8  
  11      -       ioctl(int fildes, int request, struct uscsi_cmd *cmd);
        9 +     ioctl(int filedes, int request, struct uscsi_cmd *cmd);
  12   10  
  13      -
  14   11  DESCRIPTION
  15      -       The uscsi command is very powerful and somewhat dangerous; therefore it
  16      -       has some permission restrictions. See WARNINGS for more details.
       12 +     The uscsi command is very powerful and somewhat dangerous; therefore it
       13 +     has some permission restrictions.  See WARNINGS for more details.
  17   14  
       15 +     Drivers supporting this ioctl(2) provide a general interface allowing
       16 +     user-level applications to cause individual SCSI commands to be directed
       17 +     to a particular SCSI or ATAPI device under control of that driver.  The
       18 +     uscsi command is supported by the sd(7D) driver for SCSI disks and ATAPI
       19 +     CD-ROM drives, and by the st(7D) driver for SCSI tape drives.  uscsi may
       20 +     also be supported by other device drivers; see the specific device driver
       21 +     manual page for complete information.
  18   22  
  19      -       Drivers supporting this ioctl(2) provide a general interface allowing
  20      -       user-level applications to cause individual SCSI commands to be
  21      -       directed to a particular SCSI or ATAPI device under control of that
  22      -       driver.  The uscsi command is supported by the sd driver for SCSI disks
  23      -       and ATAPI CD-ROM drives, and by the st driver for SCSI tape drives.
  24      -       uscsi may also be supported by other device drivers; see the specific
  25      -       device driver manual page for complete information.
       23 +     Applications must not assume that all Solaris disk device drivers support
       24 +     the uscsi ioctl command.  The SCSI command may include a data transfer to
       25 +     or from that device, if appropriate for that command.  Upon completion of
       26 +     the command, the user application can determine how many bytes were
       27 +     transferred and the status returned by the device.  Also, optionally, if
       28 +     the command returns a Check Condition status, the driver will
       29 +     automatically issue a Request Sense command and return the sense data
       30 +     along with the original status.  See the USCSI_RQENABLE flag below for
       31 +     this Request Sense processing.  The uscsi_cmd structure is defined in
       32 +     <sys/scsi/impl/uscsi.h> and includes the following members:
  26   33  
       34 +       int uscsi_flags;              /* read, write, etc. see below */
       35 +       short uscsi_status;           /* resulting status */
       36 +       short uscsi_timeout;          /* Command Timeout */
       37 +       caddr_t uscsi_cdb             /* CDB to send to target */
       38 +       caddr_t uscsi_bufaddr;        /* i/o source/destination */
       39 +       size_t uscsi_buflen;          /* size of i/o to take place*/
       40 +       size_t uscsi_resid;           /* resid from i/o operation */
       41 +       uchar_t uscsi_cdblen;         /* # of valid CDB bytes */
       42 +       uchar_t uscsi_rqlen;          /* size of uscsi_rqbuf */
       43 +       uchar_t uscsi_rqstatus;       /* status of request sense cmd */
       44 +       uchar_t uscsi_rqresid;        /* resid of request sense cmd */
       45 +       caddr_t uscsi_rqbuf;          /* request sense buffer */
       46 +       void *uscsi_reserved_5;       /* Reserved for future use */
  27   47  
  28      -       Applications must not assume that all Solaris disk device drivers
  29      -       support the uscsi ioctl command. The SCSI command may include a data
  30      -       transfer to or from that device, if appropriate for that command. Upon
  31      -       completion of the command, the user application can determine how many
  32      -       bytes were transferred and the status returned by the device. Also,
  33      -       optionally, if the command returns a Check Condition status, the driver
  34      -       will automatically issue a Request Sense command and return the sense
  35      -       data along with the original status. See the USCSI_RQENABLE flag below
  36      -       for this Request Sense processing. The uscsi_cmd structure is defined
  37      -       in <sys/scsi/impl/uscsi.h> and includes the following members:
       48 +     The fields of the uscsi_cmd structure have the following meanings:
  38   49  
  39      -         int uscsi_flags;               /* read, write, etc. see below */
  40      -         short uscsi_status;           /* resulting status */
  41      -         short uscsi_timeout;          /* Command Timeout */
  42      -         caddr_t uscsi_cdb             /* CDB to send to target */
  43      -         caddr_t uscsi_bufaddr;        /* i/o source/destination */
  44      -         size_t uscsi_buflen;          /* size of i/o to take place*/
  45      -         size_t uscsi_resid;           /* resid from i/o operation */
  46      -         uchar_t uscsi_cdblen;         /* # of valid CDB bytes */
  47      -         uchar_t uscsi_rqlen;          /* size of uscsi_rqbuf */
  48      -         uchar_t uscsi_rqstatus;       /* status of request sense cmd */
  49      -         uchar_t uscsi_rqresid;        /* resid of request sense cmd */
  50      -         caddr_t uscsi_rqbuf;          /* request sense buffer */
  51      -         void *uscsi_reserved_5;       /* Reserved for future use */
       50 +     uscsi_flags       The I/O direction and other details of how to carry out
       51 +                       the SCSI command.  Possible values are described below.
  52   52  
       53 +     uscsi_status      The SCSI status byte returned by the device is returned
       54 +                       in this field.
  53   55  
       56 +     uscsi_timeout     Time in seconds to allow for completion of the command.
  54   57  
  55      -       The fields of the uscsi_cmd structure have the following meanings:
       58 +     uscsi_cdb         A pointer to the SCSI CDB (command descriptor block) to
       59 +                       be transferred to the device in command phase.
  56   60  
  57      -       uscsi_flags
  58      -                           The I/O direction and other details of how to carry
  59      -                           out the SCSI command. Possible values are described
  60      -                           below.
       61 +     uscsi_bufaddr     The user buffer containing the data to be read from or
       62 +                       written to the device.
  61   63  
       64 +     uscsi_buflen      The length of uscsi_bufaddr.
  62   65  
  63      -       uscsi_status
  64      -                           The SCSI status byte returned by the device is
  65      -                           returned in this field.
       66 +     uscsi_resid       If a data transfer terminates without transferring the
       67 +                       entire requested amount, the remainder, or residue, is
       68 +                       returned in this field.
  66   69  
       70 +     uscsi_cdblen      The length of the SCSI CDB to be transferred to the
       71 +                       device in command phase.
  67   72  
  68      -       uscsi_timeout
  69      -                           Time in seconds to allow for completion of the
  70      -                           command.
       73 +     uscsi_rqlen       The length of uscsi_rqbuf, the application's Request
       74 +                       Sense buffer.
  71   75  
       76 +     uscsi_rqstatus    The SCSI status byte returned for the Request Sense
       77 +                       command executed automatically by the driver in
       78 +                       response to a Check Condition status return.
  72   79  
  73      -       uscsi_cdb
  74      -                           A pointer to the SCSI CDB (command descriptor
  75      -                           block) to be transferred to the device in command
  76      -                           phase.
       80 +     uscsi_rqresid     The residue, or untransferred data length, of the
       81 +                       Request Sense data transfer (the number of bytes, less
       82 +                       than or equal to uscsi_rqlen, which were not filled
       83 +                       with sense data).
  77   84  
       85 +     uscsi_rqbuf       Points to a buffer in application address space to
       86 +                       which the results of an automatic Request Sense command
       87 +                       are written.
  78   88  
  79      -       uscsi_bufaddr
  80      -                           The user buffer containing the data to be read from
  81      -                           or written to the device.
       89 +     uscsi_reserved_5  Reserved for future use.
  82   90  
       91 +     The uscsi_flags field defines the following:
  83   92  
  84      -       uscsi_buflen
  85      -                           The length of uscsi_bufaddr.
       93 +       USCSI_WRITE                   /* send data to device */
       94 +       USCSI_SILENT                  /* no error messages */
       95 +       USCSI_DIAGNOSE                /* fail if any error occurs */
       96 +       USCSI_ISOLATE                 /* isolate from normal commands */
       97 +       USCSI_READ                    /* get data from device */
       98 +       USCSI_ASYNC                   /* set bus to asynchronous mode */
       99 +       USCSI_SYNC                    /* return bus to sync mode if possible */
      100 +       USCSI_RESET                   /* reset target */
      101 +       USCSI_RESET_TARGET            /* reset target */
      102 +       USCSI_RESET_LUN               /* reset logical unit */
      103 +       USCSI_RESET_ALL               /* reset all targets */
      104 +       USCSI_RQENABLE                /* enable request sense extensions */
      105 +       USCSI_RENEGOT                 /* renegotiate wide/sync on next I/O */
  86  106  
      107 +     The uscsi_flags bits have the following interpretation:
  87  108  
  88      -       uscsi_resid
  89      -                           If a data transfer terminates without transferring
  90      -                           the entire requested amount, the remainder, or
  91      -                           residue, is returned in this field.
      109 +     USCSI_WRITE         Data will be written from the initiator to the
      110 +                         target.
  92  111  
      112 +     USCSI_SILENT        The driver should not print any console error
      113 +                         messages or warnings regarding failures associated
      114 +                         with this SCSI command.
  93  115  
  94      -       uscsi_cdblen
  95      -                           The length of the SCSI CDB to be transferred to the
  96      -                           device in command phase.
      116 +     USCSI_DIAGNOSE      The driver should not attempt any retries or other
      117 +                         recovery mechanisms if this SCSI command terminates
      118 +                         abnormally in any way.
  97  119  
      120 +     USCSI_ISOLATE       This SCSI command should not be executed with other
      121 +                         commands.
  98  122  
  99      -       uscsi_rqlen
 100      -                           The length of uscsi_rqbuf, the application's
 101      -                           Request Sense buffer.
      123 +     USCSI_READ          Data will be read from the target to the initiator.
 102  124  
      125 +     USCSI_ASYNC         Set the SCSI bus to asynchronous mode before running
      126 +                         this command.
 103  127  
 104      -       uscsi_rqstatus
 105      -                           The SCSI status byte returned for the Request Sense
 106      -                           command executed automatically by the driver in
 107      -                           response to a Check Condition status return.
      128 +     USCSI_SYNC          Set the SCSI bus to synchronous mode before running
      129 +                         this command.
 108  130  
      131 +     USCSI_RESET         Send a SCSI bus device reset message to this target.
 109  132  
 110      -       uscsi_rqresid
 111      -                           The residue, or untransferred data length, of the
 112      -                           Request Sense data transfer (the number of bytes,
 113      -                           less than or equal to uscsi_rqlen, which were not
 114      -                           filled with sense data).
      133 +     USCSI_RESET_TARGET  Same as USCSI_RESET.  Use this flag to request TARGET
      134 +                         RESET.  (USCSI_RESET is maintained only for
      135 +                         compatibility with old applications).
 115  136  
      137 +     USCSI_RESET_LUN     Send a SCSI logical unit reset message to this
      138 +                         target.
 116  139  
 117      -       uscsi_rqbuf
 118      -                           Points to a buffer in application address space to
 119      -                           which the results of an automatic Request Sense
 120      -                           command are written.
      140 +     USCSI_RESET_ALL     USCSI_RESET_ALL, USCSI_RESET/USCSI_RESET_TARGET, and
      141 +                         USCSI_RESET_LUN are mutually exclusive options and
      142 +                         issuing them in any simultaneous combination will
      143 +                         result in implementation-dependent behavior When a
      144 +                         USCSI reset request is combined with other SCSI
      145 +                         commands, the following semantics take effect: If the
      146 +                         USCSI RESET flag is specified, the other fields
      147 +                         (other than uscsi_flags) in the uscsi_cmd are
      148 +                         ignored.  The uscsi_cdblen field must be set to zero.
 121  149  
      150 +     USCSI_RQENABLE      Enable Request Sense extensions.  If the user
      151 +                         application is prepared to receive sense data, this
      152 +                         bit must be set, the fields uscsi_rqbuf and
      153 +                         uscsi_rqbuflen must be non-zero, and the uscsi_rqbuf
      154 +                         must point to memory writable by the application.
 122  155  
 123      -       uscsi_reserved_5
 124      -                           Reserved for future use.
      156 +     USCSI_RENEGOT       Tells USCSI to renegotiate wide mode and synchronous
      157 +                         transfer speed before the transmitted SCSI command is
      158 +                         executed.  This flag in effects tells the target
      159 +                         driver to pass the FLAG_RENEGOTIATE_WIDE_SYNC flag in
      160 +                         the SCSI packet before passing the command to an
      161 +                         adapter driver for transport.  See the scsi_pkt(9S)
      162 +                         flag FLAG_RENEGOTIATE_WIDE_SYNC for more information.
 125  163  
      164 +     The uscsi_xfer_t is a type definition that corresponds to a 64-bit
      165 +     unsigned integer.  It should be used for the USCSIMAXXFER ioctls.  This
      166 +     is used for determining the maximum transfer size that can be performed
      167 +     in a single USCSICMD ioctl.  If the SCSI request is larger than the
      168 +     specified size, then it may not work, depending on the hardware platform.
 126  169  
 127      -
 128      -       The uscsi_flags field defines the following:
 129      -
 130      -         USCSI_WRITE                   /* send data to device */
 131      -         USCSI_SILENT                  /* no error messages */
 132      -         USCSI_DIAGNOSE                /* fail if any error occurs */
 133      -         USCSI_ISOLATE                 /* isolate from normal commands */
 134      -         USCSI_READ                    /* get data from device */
 135      -         USCSI_ASYNC                   /* set bus to asynchronous mode */
 136      -         USCSI_SYNC                    /* return bus to sync mode if possible */
 137      -         USCSI_RESET                   /* reset target */
 138      -         USCSI_RESET_TARGET            /* reset target */
 139      -         USCSI_RESET_LUN               /* reset logical unit */
 140      -         USCSI_RESET_ALL               /* reset all targets */
 141      -         USCSI_RQENABLE                /* enable request sense extensions */
 142      -         USCSI_RENEGOT                 /* renegotiate wide/sync on next I/O */
 143      -
 144      -
 145      -
 146      -       The uscsi_flags bits have the following interpretation:
 147      -
 148      -       USCSI_WRITE
 149      -                             Data will be written from the initiator to the
 150      -                             target.
 151      -
 152      -
 153      -       USCSI_SILENT
 154      -                             The driver should not print any console error
 155      -                             messages or warnings regarding failures
 156      -                             associated with this SCSI command.
 157      -
 158      -
 159      -       USCSI_DIAGNOSE
 160      -                             The driver should not attempt any retries or
 161      -                             other recovery mechanisms if this SCSI command
 162      -                             terminates abnormally in any way.
 163      -
 164      -
 165      -       USCSI_ISOLATE
 166      -                             This SCSI command should not be executed with
 167      -                             other commands.
 168      -
 169      -
 170      -       USCSI_READ
 171      -                             Data will be read from the target to the
 172      -                             initiator.
 173      -
 174      -
 175      -       USCSI_ASYNC
 176      -                             Set the SCSI bus to asynchronous mode before
 177      -                             running this command.
 178      -
 179      -
 180      -       USCSI_SYNC
 181      -                             Set the SCSI bus to synchronous mode before
 182      -                             running this command.
 183      -
 184      -
 185      -       USCSI_RESET
 186      -                             Send a SCSI bus device reset message to this
 187      -                             target.
 188      -
 189      -
 190      -       USCSI_RESET_TARGET
 191      -                             Same as USCSI_RESET. Use this flag to request
 192      -                             TARGET RESET. (USCSI_RESET is maintained only for
 193      -                             compatibility with old applications).
 194      -
 195      -
 196      -       USCSI_RESET_LUN
 197      -                             Send a SCSI logical unit reset message to this
 198      -                             target.
 199      -
 200      -
 201      -       USCSI_RESET_ALL
 202      -                             USCSI_RESET_ALL, USCSI_RESET/USCSI_RESET_TARGET
 203      -                             and USCSI_RESET_LUN are mutually exclusive
 204      -                             options and issuing them in any simultaneous
 205      -                             combination will result in implementation-
 206      -                             dependent behavior
 207      -
 208      -                             When a USCSI reset request is combined with other
 209      -                             SCSI commands, the following semantics take
 210      -                             effect:
 211      -
 212      -                             If the USCSI RESET flag is specified, the other
 213      -                             fields (other than uscsi_flags) in the uscsi_cmd
 214      -                             are ignored. The uscsi_cdblen must be set to
 215      -                             zero.
 216      -
 217      -
 218      -       USCSI_RQENABLE
 219      -                             Enable Request Sense extensions. If the user
 220      -                             application is prepared to receive sense data,
 221      -                             this bit must be set, the fields uscsi_rqbuf and
 222      -                             uscsi_rqbuflen must be non-zero, and the
 223      -                             uscsi_rqbuf must point to memory writable by the
 224      -                             application.
 225      -
 226      -
 227      -       USCSI_RENEGOT
 228      -                             Tells USCSI to renegotiate wide mode and
 229      -                             synchronous transfer speed before the transmitted
 230      -                             SCSI command is executed. This flag in effects
 231      -                             tells the target driver to pass the
 232      -                             FLAG_RENEGOTIATE_WIDE_SYNC flag in the SCSI
 233      -                             packet before passing the command to an adapter
 234      -                             driver for transport.
 235      -
 236      -                             See the scsi_pkt(9S) flag
 237      -                             FLAG_RENEGOTIATE_WIDE_SYNC for more information.
 238      -
 239      -       The uscsi_xfer_t is a type definition that corresponds to a 64-bit
 240      -       unsigned integer. It should be used for the USCSIMAXXFER ioctls. This
 241      -       is used for determining the maximum transfer size that can be performed
 242      -       in a single USCSICMD ioctl. If the SCSI request is larger than the
 243      -       specified size, then it may not work, depending on the hardware
 244      -       platform.
 245      -
 246      -
 247  170  IOCTLS
 248      -       The ioctl supported by drivers providing the uscsi interface is:
      171 +     The ioctl() supported by drivers providing the uscsi interface is:
 249  172  
 250      -       USCSICMD
 251      -                   The argument is a pointer to a uscsi_cmd structure. The
      173 +     USCSICMD      The argument is a pointer to a uscsi_cmd structure.  The
 252  174                     SCSI device addressed by that driver is selected, and given
 253      -                   the SCSI command addressed by uscsi_cdb. If this command
      175 +                   the SCSI command addressed by uscsi_cdb.  If this command
 254  176                     requires a data phase, the uscsi_buflen and uscsi_bufaddr
 255  177                     fields must be set appropriately; if data phase occurs, the
 256  178                     uscsi_resid is returned as the number of bytes not
 257      -                   transferred. The status of the command, as returned by the
 258      -                   device, is returned in the uscsi_status field. If the
      179 +                   transferred.  The status of the command, as returned by the
      180 +                   device, is returned in the uscsi_status field.  If the
 259  181                     command terminates with Check Condition status, and Request
 260  182                     Sense is enabled, the sense data itself is returned in
 261      -                   uscsi_rqbuf. The uscsi_rqresid provides the residue of the
      183 +                   uscsi_rqbuf.  The uscsi_rqresid provides the residue of the
 262  184                     Request Sense data transfer.
 263  185  
 264      -
 265      -       USCSIMAXXFER
 266      -                   The argument is a pointer to a uscsi_xfer_t value. The
      186 +     USCSIMAXXFER  The argument is a pointer to a uscsi_xfer_t value.  The
 267  187                     maximum transfer size that can be used with the USCSICMD
 268  188                     ioctl for the current device will be returned in the
 269  189                     uscsi_xfer_t.
 270  190  
 271      -
 272  191                     Not all devices which support the USCSICMD ioctl also
 273  192                     support the USCSIMAXXFER ioctl.
 274  193  
 275      -
 276  194  ERRORS
 277      -       EINVAL
 278      -                 A parameter has an incorrect, or unsupported, value.
      195 +     EINVAL  A parameter has an incorrect, or unsupported, value.
 279  196  
      197 +     EIO     An error occurred during the execution of the command.
 280  198  
 281      -       EIO
 282      -                 An error occurred during the execution of the command.
      199 +     EPERM   A process without root credentials tried to execute the USCSICMD
      200 +             or USCSIMAXXFER ioctl.
 283  201  
      202 +     EFAULT  The uscsi_cmd itself, the uscsi_cdb, the uscsi_buf, the
      203 +             uscsi_rqbuf, or the uscsi_xfer_t point to an invalid address.
 284  204  
 285      -       EPERM
 286      -                 A process without root credentials tried to execute the
 287      -                 USCSICMD or USCSIMAXXFER ioctl.
      205 +STABILITY
      206 +     Committed
 288  207  
 289      -
 290      -       EFAULT
 291      -                 The uscsi_cmd itself, the uscsi_cdb, the uscsi_buf, the
 292      -                 uscsi_rqbuf, or the uscsi_xfer_t point to an invalid address.
 293      -
 294      -
 295      -ATTRIBUTES
 296      -       See attributes(5) for descriptions of the following attributes:
 297      -
 298      -
 299      -
 300      -
 301      -       +---------------------+-----------------+
 302      -       |   ATTRIBUTE TYPE    | ATTRIBUTE VALUE |
 303      -       +---------------------+-----------------+
 304      -       |Interface Stability  | Committed       |
 305      -       +---------------------+-----------------+
 306      -
 307  208  SEE ALSO
 308      -       ioctl(2), attributes(5), sd(7D), st(7D)
      209 +     ioctl(2), attributes(5), sd(7D), st(7D)
 309  210  
      211 +     ANSI Small Computer System Interface-2 (SCSI-2).
 310  212  
 311      -       ANSI Small Computer System Interface-2 (SCSI-2)
 312      -
 313  213  WARNINGS
 314      -       The uscsi command is very powerful, but somewhat dangerous, and so its
 315      -       use is restricted to processes running as root, regardless of the file
 316      -       permissions on the device node. The device driver code expects to own
 317      -       the device state, and uscsi commands can change the state of the device
 318      -       and confuse the device driver. It is best to use uscsi commands only
 319      -       with no side effects, and avoid commands such as Mode Select, as they
 320      -       may cause damage to data stored on the drive or system panics. Also, as
 321      -       the commands are not checked in any way by the device driver, any block
 322      -       may be overwritten, and the block numbers are absolute block numbers on
 323      -       the drive regardless of which slice number is used to send the command.
      214 +     The uscsi command is very powerful, but somewhat dangerous, and so its
      215 +     use is restricted to processes running as root, regardless of the file
      216 +     permissions on the device node.  The device driver code expects to own
      217 +     the device state, and uscsi commands can change the state of the device
      218 +     and confuse the device driver.  It is best to use uscsi commands only
      219 +     with no side effects, and avoid commands such as Mode Select, as they may
      220 +     cause damage to data stored on the drive or system panics.  Also, as the
      221 +     commands are not checked in any way by the device driver, any block may
      222 +     be overwritten, and the block numbers are absolute block numbers on the
      223 +     drive regardless of which slice number is used to send the command.
 324  224  
      225 +     The uscsi interface is not recommended for very large data transfers
      226 +     (typically more than 16MB).  If the requested transfer size exceeds the
      227 +     maximum transfer size of the DMA engine, it will not be broken up into
      228 +     multiple transfers and DMA errors may result.  The USCSIMAXXFER ioctl can
      229 +     be used to determine the maximum transfer size.
 325  230  
 326      -       The uscsi interface is not recommended for very large data transfers
 327      -       (typically more than 16MB). If the requested transfer size exceeds the
 328      -       maximum transfer size of the DMA engine, it will not be broken up into
 329      -       multiple transfers and DMA errors may result. The USCSIMAXXFER ioctl
 330      -       can be used to determine the maximum transfer size.
      231 +     The USCSICMD ioctl associates a struct uscsi_cmd with a device by using
      232 +     an open file descriptor to the device.  Other APIs might provide the same
      233 +     struct uscsi_cmd programming interface, but perform device association in
      234 +     some other manner.
 331  235  
 332      -
 333      -       The USCSICMD ioctl associates a struct uscsi_cmd with a device by using
 334      -       an open file descriptor to the device. Other APIs might provide the
 335      -       same struct uscsi_cmd programming interface, but perform device
 336      -       association in some other manner.
 337      -
 338      -
 339      -
 340      -                              September 23, 2016                     USCSI(7I)
      236 +illumos                        October 23, 2017                        illumos
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX