SMCIOC_READ_ELEMENT_DEVIDS

This IOCTL command issues the SCSI Read Element Status command with the device ID(DVCID) bit set and returns the element descriptors for the data transfer elements. The element_address field specifies the starting address of the first data transfer element. The number_elements field specifies the number of elements to return. The application must allocate a return buffer large enough for the number of elements that are specified in the input structure.

The input data structure is
struct read_element_devids {
   ushort element_address;            /* starting element address */
   ushort number_elements;            /* number of elements */
   struct element_devid *drive_devid; /* data transfer element pages */
};
The output data structure is
struct element_devid {
   ushort address;         /* element address                     */
   uint             :4,    /* reserved                            */
         access     :1,    /* robot access allowed                */
         except     :1,    /* abnormal element state              */
                    :1,    /* reserved                            */
         full       :1;    /* element contains medium             */
   unchar resvd1;          /* reserved                            */
   unchar asc;             /* additional sense code               */
   unchar ascq;            /* additional sense code qualifier     */
   uint  notbus     :1,    /* element not on same bus as robot    */
                    :1,    /* reserved                            */
         idvalid    :1,    /* element address valid               */
         luvalid    :1,    /* logical unit valid                  */
                    :1,    /* reserved                            */
         lun        :3;    /* logical unit number                 */
   unchar scsi;            /* scsi bus address                    */
   unchar resvd2;          /* reserved                            */
   uint  svalid     :1,    /* element address valid               */
         invert     :1,    /* medium inverted                     */
                    :6;    /* reserved                            */
   ushort source;          /* source storage element address      */
   uint             :4,    /* reserved                            */
         code_set   :4;    /* code set X'2' is all ASCII identifier*/
   uint             :4,    /* reserved                            */
         ident_type :4;    /* identifier type                     */
   unchar resvd3;          /* reserved                            */
   unchar ident_len;       /* identifier length                   */
   unchar identifier[36];  /* device identification               */
};
An example of the SMCIOC_READ_ELEMENT_DEVIDS command is
#include <sys/IBM_tape.h>
int smcioc_read_element_devids() {
int i;
struct element_devid *elem_devid, *elemp;
struct read_element_devids devids;
struct element_info element_info;
if (ioctl(fd, SMCIOC_ELEMENT_INFO, &element_info)) return errno;
if (element_info.drives) {
   elem_devid = malloc(element_info.drives
      * sizeof(struct element_devid));
   if (elem_devid == NULL) {
      errno = ENOMEM;
      return errno;
   }
   bzero((caddr_t)elem_devid,element_info.drives
      * sizeof(struct element_devid));
   devids.drive_devid = elem_devid;
   devids.element_address = element_info.drive_addr;
   devids.number_elements = element_info.drives;
   printf("Reading element device ids?\n");
   if (ioctl (fd, SMCIOC_READ_ELEMENT_DEVIDS, &devids)) {
      free(elem_devid);
      return errno;
   }
   elemp = elem_devid;
   for (i = 0; i<element_info.drives; i++, elemp++) {
      printf("\nDrive Address %d\n",elemp->address);
      if (elemp->except)
         printf(" Drive State ....................  Abnormal\n");
      else
         printf(" Drive State .................... Normal\n");
      if (elemp->asc == 0x81 && elemp->ascq ==0x00)
         printf(" ASC/ASCQ ....................... %02X%02X (Drive Present)\n",
                elemp->asc,elemp->ascq);
      else if (elemp->asc == 0x82 && elemp->ascq ==0x00)
         printf(" ASC/ASCQ ....................... %02X%02X (Drive Not Present)\n",
                elemp->asc,elemp->ascq);
      else
         printf(" ASC/ASCQ ....................... %02X%02X\n",
            elemp->asc,elemp->ascq);
      if (elemp->full)
         printf(" Media Present .................. Yes\n");
      else
         printf(" Media Present .................. No\n");
      if (elemp->access)
         printf(" Robot Access Allowed ........... Yes\n");
      else
         printf(" Robot Access Allowed ........... No\n");
      if (elemp->svalid)
         printf(" Source Element Address .........  %d\n",
            elemp->source);
      else
         printf(" Source Element Address Valid .....No\n");
      if (elemp->invert)
         printf(" Media Inverted ................. Yes\n");
      else
         printf(" Media Inverted ................. No\n");
      if (elemp->notbus)
         printf(" Same Bus as Medium Changer ..... No\n");
      else
         printf(" Same Bus as Medium Changer ..... Yes\n");
      if (elemp->idvalid)
         printf(" SCSI Bus Address ...............  %d\n",elemp->scsi);
      else
         printf(" SCSI Bus Address Valid ......... No\n");
      if (elemp->luvalid)
         printf(" Logical Unit Number ............  %d\n",elemp->lun);
      else
         printf(" Logical Unit Number Valid ...... No\n");
      printf(" Device ID ...................... %0.36s\n",
         elemp->identifier);
   }
   else {
      printf("\nNo drives found in element information\n");
   }
   free(elem_devid);
   return errno;
}