VMS Help  —  MRD Library, mrd_position_to_element
    mrd_position_to_element - Move transport to specified location

    Windows NT         mrd.dll
    UNIX               /usr/lib/libmrd.a
    OpenVMS            MRD$RTL.EXE

    #include <mrd_common.h>
    #include <mrd_message.h>

    int mrd_position_to_element(
        robot_info_t *robot_info,
        int           transport,
        int           destination,
        int           invert,
        dev_status_t *dev_status) ;

1  –  Parameters

    o  robot_info - This is the address of a robot_info_t structure
       initialized using mrd_startup(3mrd) or mrd_show(3mrd). This
       data structure contains the element starting address and
       counts for each type of element, which are needed to map an
       absolute element to the correct zero relative address and
       type.

    o  transport - The transport is the numeric value of the
       transport which will be moved.

    o  destination- The destination is an absolute element address.

    o  invert - The invert is a numeric value used to indicate if the
       medium should be inverted when it is moved. A value of one (1)
       is used to indicate that the medium should be inverted.

    o  dev_status - The dev_status is the address of a dev_status_
       t structure, which is used to pass back detailed error
       information in the event of a command failure.

2  –  Description

    This routine performs a SCSI Position to Element command. This
    command positions the trasport to the specified destination
    element. It is used by mrd_position(3mrd) function.

    The robot_info argument is the address of a robot_info_t that has
    been opened by mrd_startup(3mrd). This allows multiple position
    commands (and other commands) to be executed without having to
    repeat the startup for each command.

    The transport address is the absolute address of the transport
    element to be used for the command. Many medium changers allow
    the use of address zero (0) as the default transport, but some
    may require a transport address that is valid for the medium
    changer. For single transport medium changers, the transport
    base address of the robot_info_t structure, transport_start is a
    suitable address.

    The destination address is the absolute addresses to be used as
    the destination for the command . The absolute address can be
    calculated from a zero relative address by adding it to the base
    address for the element type. The routine makes no checks for
    the validity of the address, relying on the medium changer to do
    this.

    A invert value of one (1) can be used on medium changers that
    support inverting the transport, when this is desired; an optical
    drive with two sided media. Otherwise a value of zero should be
    used.

    This routine uses the dev_status_t structure for handing errors.
    The dev_status_t structure includes the code, os_status, and SCSI
    error fields. The following describes how to decode errors with
    the dev_status_t structure.

    SCSI Errors

    SCSI errors are indicated when the value of the valid field of
    the SCSI error is not equal to 0. The key, asc, and ascq fields
    provide additional information to help determine the cause of the
    error.

    The code usually maps the Additional Sense Code and Additional
    Sense Code Qualifier (ASC/ASCQ) values to an MRD error. The asc
    and ascq values are copied from the request sense data returned
    by the target.

    The Additional Sense Code (asc) indicates further information
    related to the error or exception condition reported in the sense
    key field. The Additional Sense Code Qualifier (ascq) indicates
    detailed information related to the additional sense code. For
    more information, consult the SCSI-2 Specification.

    Operating System Errors

    Operating system errors are indicated when the value of the valid
    field of the SCSI error is equal to 0 and the value of the os_
    status field is not equal to 0. This result is most likely caused
    by an operating system error, and probably has a mapped error in
    MRD.

    MRD Errors

    MRD errors are indicated when the value of the os_status field is
    0, and the value of the valid field of the SCSI error is 0. This
    result is most likely caused when MRD encounters its own failure.

3  –  Absolute Addresses

    The operating system interface routines use absolute SCSI element
    addresses, instead of zero relative address as used by the higher
    level functions. A zero based element address can be converted to
    an absolute address by adding the element base address from the
    robot_info_t structure. For example, the absolute slot address
    can be found by adding slot_start to the relative slot address:

     int  slot ;
     robot_info_t robot_info ;

     /*
      * An relative starting address.
      */
     slot = 3 ;

     /*
      * Becoming an absolute address.
      */
     slot += robot_info.slot_start ;

4  –  Example

    /*
     *   This is an example of using mrd_position_to_element(3mrd)
     *   to perform multiple Position To Element commands.  For
     *   each pair of arguments after the robot and transport
     *   address, it will position the transport to that location.
     *
     *      mrd_position_to_element robot transport type address
     *
     *   Type can be one of:
     *
     *      slot, port, drive or transport
     *
     *   The optional transport argument can be a transport address
     *   number, the word "default" or an empty string.  To keep the
     *   example as simple as possible, it doesn't try to invert the
     *   transport.
     */
    #ifndef   lint
    static char SccsId[] = "@(#)mrd_position_to_element.c 1.2 3/5/97" ;
    #endif

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #include <mrd_common.h>
    #include <mrd_message.h>

    /*
     *   Given a string, resembling one of the element types,
     *   return the SCSI type code for it.
     */
    struct {
       int   code ;
       char   *string ;
    } etypes[] = {
       TRANSPORT,   "transport",
       SLOT,      "slot",
       DRIVE,      "drive",
       PORT,      "port",
    } ;

    convert_type(char *etype)
    {
       register i ;

       /*
        *   For each entry in the array.
        */
       for(i = 0; i < sizeof(etypes)/sizeof(etypes[0]); i++)
          /*
           *   Do a case insensitive comparison, allowing
           *   abbreviations.  Return as soon as a match is
           *   found.  Return -1 if one isn't found.
           */
    #ifdef   vms
          if( strncmp(etypes[i].string, etype, strlen(etype)) == 0 )
    #else
          if( strncasecmp(etypes[i].string, etype, strlen(etype)) == 0 )
    #endif
             return etypes[i].code ;

       return -1 ;
    }

    main(int argc, char *argv[])
    {
       int      el ;         /* Counter */
       int      status ;      /* Status from MRD calls */
       int      invert = 0 ;      /* Don't invert */
       char      *robot ;      /* Robot name */
       int      type ;         /* Element type */
       int      element ;      /* Relative element addr */
       int      address ;      /* Absolute element addr */
       int      transport ;      /* Transport address */
       char      *transport_name ;   /* Tranport name */
       robot_info_t   robot_info ;
       dev_status_t   dev_status ;
       char      log_info[MRD_MAX_LOG_STRING+1] ;

       if( argc < 5 ) {
          printf("usage: %s robot transport type address ...\n", argv[0]);
          exit(1) ;
       }

       /*
        *   Get the medium changer name.
        */
       robot = argv[1] ;

       /*
        *   Get the transport number.  We'll keep it as a name
        *   so we can detect the default transport.  Once we
        *   know the element addresses, we can add the base
        *   base address if appropriate.
         */
       if( strcmp(argv[2], "default") == 0 )
          transport_name = NULL ;
       else
          transport_name = argv[2] ;

       /*
        *   Make sure there are pairs of arguments left.  There
        *   should be an odd number.
        */
       if((argc % 2) == 0 ) {
          printf("Pairs of arguments are required.\n") ;
          exit(1) ;
       }

       /*
        *   Open the robot.
        */
       robot_info.channel = BAD_CHANNEL ;

       status = mrd_startup(robot, &robot_info, log_info) ;

       if( status != MRD_STATUS_SUCCESS ) {
          fprintf(stderr, "Can't start %s: %s\n", robot,
             mrd_strstatus(status)) ;

          exit(1) ;
       }

       if( transport_name == NULL )
          transport = 0 ;
       else
          transport = atoi(transport_name) + robot_info.transport_start;

       /*
        *   Look at the element addresses in pairs.
        */
       for(el = 3; el < argc; el += 2) {
          type    = convert_type(argv[el]) ;
          element = atoi(argv[el + 1]) ;

          switch( type ) {
          case SLOT:
             address = element + robot_info.slot_start ;
             break ;
          case DRIVE:
             address = element + robot_info.device_start ;
             break ;
          case TRANSPORT:
             address = element + robot_info.transport_start ;
             break ;
          case PORT:
             address = element + robot_info.port_start ;
             break ;
          default:
             printf("Unknown element type: %s %s\n", argv[el],
                argv[el + 1]) ;

             continue ;
          }

          /*
           *   Audit the command.
           */
          printf("Position transport to %s #%d.\n", mrd_strelement(type),
             element) ;

          /*
           *   Do the command.
           */
          status = mrd_position_to_element(&robot_info, transport,
                    address, invert, &dev_status) ;

          if( status != MRD_STATUS_SUCCESS )
             printf("Position to Element failed: %s: %s.\n", robot,
                mrd_strstatus(status)) ;
       }

       (void)mrd_shutdown(&robot_info) ;

       return 0 ;
    }

5  –  Return Values

    Upon successful completion, mrd_position_to_element(3mrd) will
    return MRD_STATUS_SUCCESS. On a failure, an MRD_STATUS value
    corresponding to the error will be returned. Common errors are:

5.1  –  MRD_STATUS_PARAM

    This error is returned if the robot_info or dev_status arguments
    are NULL pointers.

5.2  –  MRD_STATUS_ROBOT_ILLEGAL_REQUEST

    This error occurs when the medium changer does not support the
    Position To Element command. The seven and five slot DLT loaders
    do not support the command, though the TL820 and TL810 family
    libraries do. Some models of TLZ6L and TLZ7L do not support the
    command and may take a long time to fail.

    It is also used for a SCSI command failure, when the ASC is set
    to one of:

    o  0x1A - Parameter list length error

    o  0x20 - Invalid command operation code

    o  0x22 - Unsupported command

    o  0x24 - Illegal field in CDB

    o  0x25 - Logical unit not supported

    o  0x26 - Threshold parameters not supported

    o  0x28 - Import or Export element accessed

    o  0x2C - Command sequence error

    o  0x39 - Saving parameters not supported

    o  0x3D - Invalid bits in Identify message

    o  0x53 - Medium removal prevented

    This status is also returned when the ASC and ASCQ are zero, but
    the key is five (5).

5.3  –  MRD_STATUS_ELEMENT_INVALID

    This error occurs when a SCSI command fails with the ASC set to
    0x21. The log_info will contain the ASCQ. This indicates that an
    invalid element address reached the medium-changer. For example,
    specifying the 13th slot when only 12 slots are present.

5.4  –  MRD_STATUS_IVCHAN

    This error code is used when an OpenVMS system service fails
    with the status SS$_IVCHAN. It is likely when an operating system
    specific routine is used on a device that hasn't been opened by
    mrd_startup(3mrd).

6  –  Related Functions

    Functions:

    mrd_position(3mrd)
Close Help