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_elements 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 */
uchar resvd1; /* reserved */
uchar asc; /* additional sense code */
uchar 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 */
uchar scsi; /* scsi bus address */
uchar 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 */
uchar resvd3; /* reserved */
uchar ident_len; /* identifier length */
uchar identifier[36]; /* device identification */
};
An example of the SMCIOC_READ_ELEMENT_DEVIDS command
is
#include <sys/Atape.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;
}